storage/: remove reverse-key-listing feature
We don't use reverse listing in any of our code, outside of tests, and it is only exposed through libuplink in the lib/uplink.(*Project).ListBuckets() API. We also don't know of any users who might have a need for reverse listing through ListBuckets(). Since one of our prospective pointerdb backends can not support backwards iteration, and because of the above considerations, we are going to remove the reverse listing feature. Change-Id: I8d2a1f33d01ee70b79918d584b8c671f57eef2a0
This commit is contained in:
parent
28a70200d7
commit
0c025fa937
@ -91,7 +91,7 @@ func TestDownloadWithSomeNodesOffline(t *testing.T) {
|
|||||||
|
|
||||||
// get a remote segment from pointerdb
|
// get a remote segment from pointerdb
|
||||||
pdb := satellite.Metainfo.Service
|
pdb := satellite.Metainfo.Service
|
||||||
listResponse, _, err := pdb.List(ctx, "", "", "", true, 0, 0)
|
listResponse, _, err := pdb.List(ctx, "", "", true, 0, 0)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var path string
|
var path string
|
||||||
@ -195,7 +195,7 @@ func TestDownloadFromUnresponsiveNode(t *testing.T) {
|
|||||||
|
|
||||||
// get a remote segment from pointerdb
|
// get a remote segment from pointerdb
|
||||||
pdb := planet.Satellites[0].Metainfo.Service
|
pdb := planet.Satellites[0].Metainfo.Service
|
||||||
listResponse, _, err := pdb.List(ctx, "", "", "", true, 0, 0)
|
listResponse, _, err := pdb.List(ctx, "", "", true, 0, 0)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var path string
|
var path string
|
||||||
|
@ -1310,7 +1310,7 @@ type ListSegmentsRequestOld struct {
|
|||||||
Bucket []byte `protobuf:"bytes,1,opt,name=bucket,proto3" json:"bucket,omitempty"`
|
Bucket []byte `protobuf:"bytes,1,opt,name=bucket,proto3" json:"bucket,omitempty"`
|
||||||
Prefix []byte `protobuf:"bytes,2,opt,name=prefix,proto3" json:"prefix,omitempty"`
|
Prefix []byte `protobuf:"bytes,2,opt,name=prefix,proto3" json:"prefix,omitempty"`
|
||||||
StartAfter []byte `protobuf:"bytes,3,opt,name=start_after,json=startAfter,proto3" json:"start_after,omitempty"`
|
StartAfter []byte `protobuf:"bytes,3,opt,name=start_after,json=startAfter,proto3" json:"start_after,omitempty"`
|
||||||
EndBefore []byte `protobuf:"bytes,4,opt,name=end_before,json=endBefore,proto3" json:"end_before,omitempty"`
|
EndBefore []byte `protobuf:"bytes,4,opt,name=end_before,json=endBefore,proto3" json:"end_before,omitempty"` // Deprecated: Do not use.
|
||||||
Recursive bool `protobuf:"varint,5,opt,name=recursive,proto3" json:"recursive,omitempty"`
|
Recursive bool `protobuf:"varint,5,opt,name=recursive,proto3" json:"recursive,omitempty"`
|
||||||
Limit int32 `protobuf:"varint,6,opt,name=limit,proto3" json:"limit,omitempty"`
|
Limit int32 `protobuf:"varint,6,opt,name=limit,proto3" json:"limit,omitempty"`
|
||||||
MetaFlags uint32 `protobuf:"fixed32,7,opt,name=meta_flags,json=metaFlags,proto3" json:"meta_flags,omitempty"`
|
MetaFlags uint32 `protobuf:"fixed32,7,opt,name=meta_flags,json=metaFlags,proto3" json:"meta_flags,omitempty"`
|
||||||
@ -1371,6 +1371,7 @@ func (m *ListSegmentsRequestOld) GetStartAfter() []byte {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: Do not use.
|
||||||
func (m *ListSegmentsRequestOld) GetEndBefore() []byte {
|
func (m *ListSegmentsRequestOld) GetEndBefore() []byte {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.EndBefore
|
return m.EndBefore
|
||||||
@ -5133,239 +5134,239 @@ func init() {
|
|||||||
func init() { proto.RegisterFile("metainfo.proto", fileDescriptor_631e2f30a93cd64e) }
|
func init() { proto.RegisterFile("metainfo.proto", fileDescriptor_631e2f30a93cd64e) }
|
||||||
|
|
||||||
var fileDescriptor_631e2f30a93cd64e = []byte{
|
var fileDescriptor_631e2f30a93cd64e = []byte{
|
||||||
// 3709 bytes of a gzipped FileDescriptorProto
|
// 3712 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5b, 0x4b, 0x6c, 0x1c, 0x59,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x5b, 0x5d, 0x6c, 0x1c, 0x57,
|
||||||
0xd5, 0x76, 0xbf, 0xbb, 0x4f, 0xb7, 0xdd, 0xdd, 0xd7, 0x8e, 0xdd, 0x29, 0xc7, 0x71, 0x52, 0x49,
|
0xf5, 0xf7, 0xec, 0xf7, 0x9e, 0x5d, 0x7b, 0xd7, 0xd7, 0x8e, 0xbd, 0x19, 0xc7, 0x71, 0x32, 0x49,
|
||||||
0x66, 0xfc, 0xeb, 0x9f, 0x71, 0x46, 0x9e, 0xff, 0x47, 0x83, 0x92, 0x61, 0xb0, 0xd3, 0x9e, 0x74,
|
0x5a, 0xff, 0xf5, 0x6f, 0x9d, 0xca, 0x05, 0x54, 0x94, 0x94, 0x62, 0x67, 0xdd, 0x78, 0x9b, 0xd8,
|
||||||
0x4f, 0x62, 0xc7, 0x53, 0x4e, 0x26, 0x21, 0x0c, 0xb4, 0xca, 0x5d, 0xd7, 0x76, 0x91, 0xee, 0xae,
|
0x71, 0xc7, 0x49, 0x13, 0x42, 0x61, 0x35, 0xde, 0xb9, 0xb6, 0x87, 0xec, 0xee, 0x2c, 0x33, 0xb3,
|
||||||
0xa6, 0xaa, 0x7a, 0xc6, 0x19, 0x56, 0x48, 0x23, 0x21, 0x04, 0x42, 0x23, 0xd6, 0x88, 0xd5, 0xec,
|
0xad, 0x53, 0x9e, 0x90, 0x2a, 0x21, 0x84, 0x84, 0x2a, 0x9e, 0x11, 0x4f, 0x7d, 0xe3, 0x09, 0xde,
|
||||||
0x58, 0xc1, 0x0e, 0x09, 0xd8, 0x02, 0x12, 0x1a, 0xa4, 0x11, 0x62, 0xc1, 0x62, 0x60, 0xc5, 0x0e,
|
0x90, 0x80, 0x57, 0x40, 0x42, 0x45, 0xaa, 0x10, 0x0f, 0x3c, 0x14, 0x9e, 0x78, 0x83, 0x17, 0xde,
|
||||||
0x36, 0xec, 0x40, 0x48, 0xe8, 0xbe, 0xea, 0x5d, 0xfd, 0xf0, 0x23, 0x61, 0x76, 0x55, 0xe7, 0x9e,
|
0x40, 0x48, 0xe8, 0x7e, 0xcd, 0xf7, 0xec, 0x87, 0x3f, 0x12, 0xfa, 0x36, 0x73, 0xee, 0xb9, 0x67,
|
||||||
0x7b, 0xea, 0xde, 0xf3, 0xf8, 0xce, 0xa9, 0x73, 0xab, 0x60, 0xa6, 0x8b, 0x6d, 0x55, 0xef, 0xed,
|
0xee, 0x3d, 0x1f, 0xbf, 0x73, 0xe6, 0xdc, 0x19, 0x98, 0xea, 0x60, 0x47, 0x33, 0xba, 0xfb, 0xe6,
|
||||||
0x1b, 0xab, 0x7d, 0xd3, 0xb0, 0x0d, 0x94, 0x17, 0xf7, 0x52, 0x05, 0xf7, 0xda, 0xe6, 0xd3, 0xbe,
|
0x4a, 0xcf, 0x32, 0x1d, 0x13, 0x15, 0xc4, 0xbd, 0x5c, 0xc5, 0xdd, 0x96, 0xf5, 0xb4, 0xe7, 0x18,
|
||||||
0xad, 0x1b, 0x3d, 0x36, 0x26, 0xc1, 0x81, 0x71, 0xc0, 0xf9, 0xa4, 0xe5, 0x03, 0xc3, 0x38, 0xe8,
|
0x66, 0x97, 0x8d, 0xc9, 0x70, 0x60, 0x1e, 0x70, 0x3e, 0x79, 0xe9, 0xc0, 0x34, 0x0f, 0xda, 0xf8,
|
||||||
0xe0, 0xeb, 0xf4, 0x6e, 0x6f, 0xb0, 0x7f, 0xdd, 0xd6, 0xbb, 0xd8, 0xb2, 0xd5, 0x6e, 0x5f, 0x30,
|
0x3a, 0xbd, 0xdb, 0xeb, 0xef, 0x5f, 0x77, 0x8c, 0x0e, 0xb6, 0x1d, 0xad, 0xd3, 0x13, 0xcc, 0x5d,
|
||||||
0xf7, 0x0c, 0x0d, 0xf3, 0xeb, 0x72, 0xdf, 0xd0, 0x7b, 0x36, 0x36, 0xb5, 0x3d, 0x4e, 0x28, 0x19,
|
0x53, 0xc7, 0xfc, 0xba, 0xd2, 0x33, 0x8d, 0xae, 0x83, 0x2d, 0x7d, 0x8f, 0x13, 0xca, 0xa6, 0xa5,
|
||||||
0xa6, 0x86, 0x4d, 0x8b, 0xdd, 0xc9, 0x2b, 0x30, 0xad, 0xe0, 0x6f, 0x0e, 0xb0, 0x65, 0x37, 0xb0,
|
0x63, 0xcb, 0x66, 0x77, 0xca, 0x32, 0x4c, 0xaa, 0xf8, 0xdb, 0x7d, 0x6c, 0x3b, 0x9b, 0x58, 0xd3,
|
||||||
0xaa, 0x61, 0x13, 0x2d, 0x40, 0x4e, 0xed, 0xeb, 0xad, 0x27, 0xf8, 0x69, 0x2d, 0x71, 0x29, 0xb1,
|
0xb1, 0x85, 0xe6, 0x21, 0xaf, 0xf5, 0x8c, 0xe6, 0x13, 0xfc, 0xb4, 0x26, 0x5d, 0x92, 0x96, 0xcb,
|
||||||
0x52, 0x52, 0xb2, 0x6a, 0x5f, 0xbf, 0x83, 0x9f, 0xca, 0x3f, 0x49, 0x41, 0x76, 0x63, 0xd0, 0x7e,
|
0x6a, 0x4e, 0xeb, 0x19, 0x77, 0xf0, 0x53, 0xe5, 0xa7, 0x69, 0xc8, 0xad, 0xf7, 0x5b, 0x4f, 0xb0,
|
||||||
0x82, 0x6d, 0x84, 0x20, 0xdd, 0x53, 0xbb, 0x98, 0x33, 0xd0, 0x6b, 0xf4, 0x1a, 0x14, 0xfb, 0xaa,
|
0x83, 0x10, 0x64, 0xba, 0x5a, 0x07, 0x73, 0x06, 0x7a, 0x8d, 0x5e, 0x83, 0x52, 0x4f, 0x73, 0x0e,
|
||||||
0x7d, 0xd8, 0x6a, 0xeb, 0xfd, 0x43, 0x6c, 0xd6, 0x92, 0x97, 0x12, 0x2b, 0x33, 0x6b, 0x0b, 0xab,
|
0x9b, 0x2d, 0xa3, 0x77, 0x88, 0xad, 0x5a, 0xea, 0x92, 0xb4, 0x3c, 0xb5, 0x3a, 0xbf, 0xe2, 0xdb,
|
||||||
0x9e, 0x8d, 0xdc, 0xa2, 0x23, 0xbb, 0x03, 0xdd, 0xc6, 0x0a, 0x10, 0x5e, 0x46, 0x40, 0xb7, 0x00,
|
0xc8, 0x2d, 0x3a, 0xb2, 0xdb, 0x37, 0x1c, 0xac, 0x02, 0xe1, 0x65, 0x04, 0x74, 0x0b, 0xa0, 0x65,
|
||||||
0xda, 0x26, 0x56, 0x6d, 0xac, 0xb5, 0x54, 0xbb, 0x96, 0xba, 0x94, 0x58, 0x29, 0xae, 0x49, 0xab,
|
0x61, 0xcd, 0xc1, 0x7a, 0x53, 0x73, 0x6a, 0xe9, 0x4b, 0xd2, 0x72, 0x69, 0x55, 0x5e, 0x61, 0x7b,
|
||||||
0x6c, 0x8f, 0xab, 0x62, 0x8f, 0xab, 0xf7, 0xc5, 0x1e, 0x37, 0xf2, 0xbf, 0xf9, 0x6c, 0x79, 0xea,
|
0x5c, 0x11, 0x7b, 0x5c, 0xb9, 0x2f, 0xf6, 0xb8, 0x5e, 0xf8, 0xed, 0x67, 0x4b, 0x13, 0x1f, 0xfd,
|
||||||
0xa3, 0x3f, 0x2f, 0x27, 0x94, 0x02, 0x9f, 0xb7, 0x6e, 0xa3, 0x57, 0x60, 0x4e, 0xc3, 0xfb, 0xea,
|
0x65, 0x49, 0x52, 0x8b, 0x7c, 0xde, 0x9a, 0x83, 0x5e, 0x81, 0x59, 0x1d, 0xef, 0x6b, 0xfd, 0xb6,
|
||||||
0xa0, 0x63, 0xb7, 0x2c, 0x7c, 0xd0, 0xc5, 0x3d, 0xbb, 0x65, 0xe9, 0x1f, 0xe0, 0x5a, 0xfa, 0x52,
|
0xd3, 0xb4, 0xf1, 0x41, 0x07, 0x77, 0x9d, 0xa6, 0x6d, 0x7c, 0x80, 0x6b, 0x99, 0x4b, 0xd2, 0x72,
|
||||||
0x62, 0x25, 0xa5, 0x20, 0x3e, 0xb6, 0xcb, 0x86, 0x76, 0xf5, 0x0f, 0x30, 0x7a, 0x08, 0xe7, 0xc5,
|
0x5a, 0x45, 0x7c, 0x6c, 0x97, 0x0d, 0xed, 0x1a, 0x1f, 0x60, 0xf4, 0x10, 0xce, 0x8b, 0x19, 0x16,
|
||||||
0x0c, 0x13, 0x6b, 0x83, 0x9e, 0xa6, 0xf6, 0xda, 0x4f, 0x5b, 0x56, 0xfb, 0x10, 0x77, 0x71, 0x2d,
|
0xd6, 0xfb, 0x5d, 0x5d, 0xeb, 0xb6, 0x9e, 0x36, 0xed, 0xd6, 0x21, 0xee, 0xe0, 0x5a, 0x96, 0xae,
|
||||||
0x43, 0x57, 0xb1, 0xb8, 0xea, 0x2a, 0x4f, 0x71, 0x78, 0x76, 0x29, 0x8b, 0xb2, 0xc0, 0x67, 0x07,
|
0x62, 0x61, 0xc5, 0x53, 0x9e, 0xea, 0xf2, 0xec, 0x52, 0x16, 0x75, 0x9e, 0xcf, 0x0e, 0x0f, 0x20,
|
||||||
0x07, 0x90, 0x06, 0x4b, 0x42, 0xb0, 0xbb, 0xfb, 0x56, 0x5f, 0x35, 0xd5, 0x2e, 0xb6, 0xb1, 0x69,
|
0x1d, 0x16, 0x85, 0x60, 0x6f, 0xf7, 0xcd, 0x9e, 0x66, 0x69, 0x1d, 0xec, 0x60, 0xcb, 0xae, 0xe5,
|
||||||
0xd5, 0xb2, 0x54, 0xf8, 0x25, 0xaf, 0x6e, 0x36, 0x9d, 0xcb, 0x1d, 0x87, 0x4f, 0x59, 0xe4, 0x62,
|
0xa8, 0xf0, 0x4b, 0x7e, 0xdd, 0x6c, 0xb8, 0x97, 0x3b, 0x2e, 0x9f, 0xba, 0xc0, 0xc5, 0xc4, 0x0d,
|
||||||
0xa2, 0x06, 0xd1, 0x12, 0x40, 0x5f, 0x35, 0xed, 0x1e, 0x36, 0x5b, 0xba, 0x56, 0xcb, 0x51, 0x4b,
|
0xa2, 0x45, 0x80, 0x9e, 0x66, 0x39, 0x5d, 0x6c, 0x35, 0x0d, 0xbd, 0x96, 0xa7, 0x96, 0x28, 0x72,
|
||||||
0x14, 0x38, 0xa5, 0xa9, 0xc9, 0x3a, 0xcc, 0x30, 0x63, 0xdd, 0xd5, 0x2d, 0xbb, 0x69, 0xe3, 0x6e,
|
0x4a, 0x43, 0x57, 0x0c, 0x98, 0x62, 0xc6, 0xba, 0x6b, 0xd8, 0x4e, 0xc3, 0xc1, 0x9d, 0x58, 0xa3,
|
||||||
0xa4, 0xd1, 0xfc, 0xaa, 0x4f, 0x1e, 0x4b, 0xf5, 0xf2, 0xc7, 0x29, 0x98, 0x65, 0xcf, 0xba, 0x45,
|
0x05, 0x55, 0x9f, 0x3a, 0x96, 0xea, 0x95, 0x8f, 0xd3, 0x30, 0xc3, 0x9e, 0x75, 0x8b, 0xd2, 0xb8,
|
||||||
0x69, 0xdc, 0x9f, 0xd0, 0x75, 0xc8, 0x1e, 0x52, 0x9f, 0xaa, 0x95, 0xa9, 0xe0, 0x85, 0x55, 0xc7,
|
0x3f, 0xa1, 0xeb, 0x90, 0x3b, 0xa4, 0x3e, 0x55, 0xab, 0x50, 0xc1, 0xf3, 0x2b, 0xae, 0xbf, 0x07,
|
||||||
0xdf, 0x7d, 0x2e, 0xa7, 0x70, 0xb6, 0x53, 0x76, 0xab, 0x38, 0x8f, 0x48, 0x1d, 0xcf, 0x23, 0xd2,
|
0x5c, 0x4e, 0xe5, 0x6c, 0xa7, 0xec, 0x56, 0x49, 0x1e, 0x91, 0x3e, 0x9e, 0x47, 0x64, 0xce, 0xd2,
|
||||||
0x67, 0xe9, 0x11, 0x99, 0xd3, 0xf7, 0x88, 0x6c, 0xd0, 0x23, 0xbe, 0x0c, 0x73, 0x7e, 0x2b, 0x59,
|
0x23, 0xb2, 0xa7, 0xef, 0x11, 0xb9, 0xb0, 0x47, 0x7c, 0x15, 0x66, 0x83, 0x56, 0xb2, 0x7b, 0x66,
|
||||||
0x7d, 0xa3, 0x67, 0x61, 0xb4, 0x02, 0xd9, 0x3d, 0x4a, 0xa7, 0x7a, 0x2f, 0xae, 0x55, 0x5c, 0x33,
|
0xd7, 0xc6, 0x68, 0x19, 0x72, 0x7b, 0x94, 0x4e, 0xf5, 0x5e, 0x5a, 0xad, 0x7a, 0x66, 0x62, 0xfc,
|
||||||
0x31, 0x7e, 0x85, 0x8f, 0xcb, 0x0f, 0xa1, 0xc2, 0x28, 0xb7, 0xb1, 0x7d, 0x9a, 0x46, 0x96, 0x5f,
|
0x2a, 0x1f, 0x57, 0x1e, 0x42, 0x95, 0x51, 0x6e, 0x63, 0xe7, 0x34, 0x8d, 0xac, 0xbc, 0x0e, 0xd3,
|
||||||
0x87, 0xaa, 0x47, 0xf0, 0xc4, 0xeb, 0x7a, 0x2c, 0xfc, 0xaf, 0x8e, 0x3b, 0xf8, 0x74, 0xfd, 0x4f,
|
0x3e, 0xc1, 0x63, 0xaf, 0xeb, 0xb1, 0xf0, 0xbf, 0x3a, 0x6e, 0xe3, 0xd3, 0xf5, 0x3f, 0x65, 0x4e,
|
||||||
0x9e, 0x17, 0x5a, 0x13, 0xb2, 0xd9, 0xea, 0xe4, 0x8f, 0x12, 0x62, 0xcd, 0x24, 0xc0, 0x8e, 0xfd,
|
0x68, 0x4d, 0xc8, 0x66, 0xab, 0x53, 0x3e, 0x92, 0xc4, 0x9a, 0x49, 0x80, 0x1d, 0xfb, 0x91, 0x73,
|
||||||
0xc8, 0x79, 0xc8, 0xb6, 0x07, 0xa6, 0x65, 0x98, 0x02, 0x6c, 0xd9, 0x1d, 0x9a, 0x83, 0x4c, 0x47,
|
0x90, 0x6b, 0xf5, 0x2d, 0xdb, 0xb4, 0x04, 0xd8, 0xb2, 0x3b, 0x34, 0x0b, 0xd9, 0xb6, 0xd1, 0x31,
|
||||||
0xef, 0xea, 0x2c, 0x26, 0x33, 0x0a, 0xbb, 0x41, 0x17, 0xa0, 0xa0, 0xe9, 0x26, 0x6e, 0x13, 0xc3,
|
0x58, 0x4c, 0x66, 0x55, 0x76, 0x83, 0x2e, 0x40, 0x51, 0x37, 0x2c, 0xdc, 0x22, 0x86, 0xa7, 0x7e,
|
||||||
0x53, 0x3f, 0xce, 0x28, 0x2e, 0x41, 0x7e, 0x04, 0xc8, 0xbb, 0x22, 0xae, 0xc6, 0x55, 0xc8, 0xe8,
|
0x9c, 0x55, 0x3d, 0x82, 0xf2, 0x08, 0x90, 0x7f, 0x45, 0x5c, 0x8d, 0x2b, 0x90, 0x35, 0x1c, 0xdc,
|
||||||
0x36, 0xee, 0x5a, 0xb5, 0xc4, 0xa5, 0xd4, 0x4a, 0x71, 0xad, 0x16, 0xd4, 0xa2, 0xc0, 0x07, 0x85,
|
0xb1, 0x6b, 0xd2, 0xa5, 0xf4, 0x72, 0x69, 0xb5, 0x16, 0xd6, 0xa2, 0xc0, 0x07, 0x95, 0xb1, 0x11,
|
||||||
0xb1, 0x11, 0x25, 0x74, 0x0d, 0x13, 0xd3, 0x07, 0xe7, 0x15, 0x7a, 0x2d, 0x7f, 0x3b, 0x01, 0x8b,
|
0x25, 0x74, 0x4c, 0x0b, 0xd3, 0x07, 0x17, 0x54, 0x7a, 0xad, 0x7c, 0x57, 0x82, 0x05, 0xc6, 0xbd,
|
||||||
0x8c, 0x7b, 0x17, 0xdb, 0xeb, 0xb6, 0x6d, 0xea, 0x7b, 0x03, 0xf2, 0xc8, 0x53, 0x8d, 0x74, 0xbf,
|
0x8b, 0x9d, 0x35, 0xc7, 0xb1, 0x8c, 0xbd, 0x3e, 0x79, 0xe4, 0xa9, 0x46, 0x7a, 0xd0, 0x7d, 0x53,
|
||||||
0xfb, 0x26, 0x83, 0xee, 0x7b, 0x11, 0x2e, 0x44, 0x2f, 0x81, 0x1b, 0xe4, 0xc3, 0x04, 0xcc, 0xae,
|
0x61, 0xf7, 0xbd, 0x08, 0x17, 0xe2, 0x97, 0xc0, 0x0d, 0xf2, 0xa1, 0x04, 0x33, 0x6b, 0xba, 0x6e,
|
||||||
0x6b, 0x9a, 0x89, 0x2d, 0x0b, 0x6b, 0xf7, 0x48, 0x8a, 0xbb, 0x4b, 0x75, 0xb6, 0x22, 0x34, 0xc9,
|
0x61, 0xdb, 0xc6, 0xfa, 0x3d, 0x92, 0xe2, 0xee, 0x52, 0x9d, 0x2d, 0x0b, 0x4d, 0x32, 0x2f, 0x42,
|
||||||
0xbc, 0x08, 0xad, 0xf2, 0xf4, 0xe7, 0xb2, 0x08, 0xed, 0xde, 0x82, 0x39, 0xcb, 0x36, 0x4c, 0xf5,
|
0x2b, 0x3c, 0xfd, 0x79, 0x2c, 0x42, 0xbb, 0xb7, 0x60, 0xd6, 0x76, 0x4c, 0x4b, 0x3b, 0xc0, 0x4d,
|
||||||
0x00, 0xb7, 0x48, 0xfe, 0x6c, 0xa9, 0x4c, 0x1a, 0x87, 0xc5, 0xea, 0x2a, 0x4d, 0xaa, 0xdb, 0x86,
|
0x92, 0x3f, 0x9b, 0x1a, 0x93, 0xc6, 0x61, 0x71, 0x7a, 0x85, 0x26, 0xd5, 0x6d, 0x53, 0xc7, 0xfc,
|
||||||
0x86, 0xf9, 0x63, 0x14, 0xc4, 0xd9, 0x3d, 0x34, 0xf9, 0xf7, 0x49, 0x98, 0xe7, 0x98, 0xf2, 0xd0,
|
0x31, 0x2a, 0xe2, 0xec, 0x3e, 0x9a, 0xf2, 0x87, 0x14, 0xcc, 0x71, 0x4c, 0x79, 0x68, 0x19, 0xae,
|
||||||
0xd4, 0x1d, 0x67, 0xbc, 0xd7, 0xd1, 0x8e, 0xe5, 0x1c, 0x9e, 0x08, 0x28, 0x09, 0x7f, 0x27, 0xda,
|
0x33, 0xde, 0x6b, 0xeb, 0xc7, 0x72, 0x0e, 0x5f, 0x04, 0x94, 0x85, 0xbf, 0x13, 0xed, 0x11, 0x9c,
|
||||||
0x23, 0x38, 0xc7, 0x75, 0x44, 0xaf, 0x51, 0x0d, 0x72, 0x1c, 0xe5, 0x38, 0xc0, 0x89, 0x5b, 0x74,
|
0xe3, 0x3a, 0xa2, 0xd7, 0xa8, 0x06, 0x79, 0x8e, 0x72, 0x1c, 0xe0, 0xc4, 0x2d, 0xba, 0x01, 0xe0,
|
||||||
0x03, 0xc0, 0x45, 0xb3, 0x71, 0x60, 0xcc, 0xc3, 0x8e, 0x6e, 0x80, 0xd4, 0x55, 0x8f, 0x04, 0x6a,
|
0xa1, 0xd9, 0x28, 0x30, 0xe6, 0x63, 0x47, 0x37, 0x40, 0xee, 0x68, 0x47, 0x02, 0xb5, 0xb0, 0x1e,
|
||||||
0x61, 0xcd, 0x0f, 0xa5, 0x19, 0xfa, 0xa4, 0x85, 0xae, 0x7a, 0xb4, 0x29, 0x18, 0xbc, 0x78, 0x5a,
|
0x84, 0xd2, 0x2c, 0x7d, 0xd2, 0x7c, 0x47, 0x3b, 0xda, 0x10, 0x0c, 0x7e, 0x3c, 0xad, 0x03, 0xe0,
|
||||||
0x07, 0xc0, 0x47, 0x7d, 0xdd, 0x54, 0xa9, 0xbf, 0x66, 0x27, 0xc8, 0x2e, 0x9e, 0x79, 0xf2, 0xa7,
|
0xa3, 0x9e, 0x61, 0x69, 0xd4, 0x5f, 0x73, 0x63, 0x64, 0x17, 0xdf, 0x3c, 0xe5, 0x53, 0x09, 0xe6,
|
||||||
0x09, 0x58, 0xf0, 0x6b, 0x94, 0x59, 0x9c, 0xa8, 0xb4, 0x01, 0x15, 0x55, 0xd8, 0xbc, 0x45, 0xad,
|
0x83, 0x1a, 0x65, 0x16, 0x27, 0x2a, 0xdd, 0x84, 0xaa, 0x26, 0x6c, 0xde, 0xa4, 0x56, 0x14, 0x7e,
|
||||||
0x28, 0xfc, 0x7c, 0xc9, 0x55, 0x6e, 0x84, 0x57, 0x28, 0x65, 0x67, 0x1a, 0xbd, 0xb7, 0xd0, 0xab,
|
0xbe, 0xe8, 0x29, 0x37, 0xc6, 0x2b, 0xd4, 0x8a, 0x3b, 0x8d, 0xde, 0xdb, 0xe8, 0x55, 0x98, 0xb4,
|
||||||
0x30, 0x6d, 0x1a, 0x86, 0xdd, 0xea, 0xeb, 0xb8, 0x8d, 0x1d, 0x07, 0xdc, 0x28, 0x93, 0x25, 0xfd,
|
0x4c, 0xd3, 0x69, 0xf6, 0x0c, 0xdc, 0xc2, 0xae, 0x03, 0xae, 0x57, 0xc8, 0x92, 0xfe, 0xfc, 0xd9,
|
||||||
0xe9, 0xb3, 0xe5, 0xdc, 0x0e, 0xa1, 0x37, 0xeb, 0x4a, 0x91, 0x70, 0xb1, 0x1b, 0x8d, 0x26, 0x27,
|
0x52, 0x7e, 0x87, 0xd0, 0x1b, 0x75, 0xb5, 0x44, 0xb8, 0xd8, 0x8d, 0x4e, 0x93, 0x93, 0x65, 0xbc,
|
||||||
0x53, 0x7f, 0x4f, 0xb5, 0x31, 0xad, 0x97, 0x52, 0x74, 0xca, 0x02, 0x9f, 0x52, 0xa6, 0x5c, 0x3b,
|
0xa7, 0x39, 0x98, 0xd6, 0x4b, 0x69, 0x3a, 0x65, 0x9e, 0x4f, 0xa9, 0x50, 0xae, 0x1d, 0x36, 0x7e,
|
||||||
0x6c, 0xfc, 0x0e, 0x7e, 0xaa, 0x40, 0xdf, 0xb9, 0x96, 0xff, 0xe5, 0x6e, 0xea, 0x96, 0xd1, 0x25,
|
0x07, 0x3f, 0x55, 0xa1, 0xe7, 0x5e, 0x2b, 0xff, 0xf6, 0x36, 0x75, 0xcb, 0xec, 0x90, 0x15, 0x3d,
|
||||||
0x2b, 0x7a, 0xee, 0x7e, 0xf2, 0x12, 0xe4, 0xb8, 0x53, 0x70, 0x27, 0x41, 0x1e, 0x27, 0xd9, 0x61,
|
0x77, 0x3f, 0x79, 0x09, 0xf2, 0xdc, 0x29, 0xb8, 0x93, 0x20, 0x9f, 0x93, 0xec, 0xb0, 0x2b, 0x55,
|
||||||
0x57, 0x8a, 0x60, 0x41, 0x37, 0xa0, 0x6c, 0x98, 0xfa, 0x81, 0xde, 0x53, 0x3b, 0x42, 0xf1, 0x19,
|
0xb0, 0xa0, 0x1b, 0x50, 0x31, 0x2d, 0xe3, 0xc0, 0xe8, 0x6a, 0x6d, 0xa1, 0xf8, 0x2c, 0x55, 0x7c,
|
||||||
0xaa, 0xf8, 0xa8, 0x00, 0x9b, 0x11, 0xac, 0x4c, 0xd9, 0x72, 0x03, 0x6a, 0x81, 0xcd, 0xbb, 0x26,
|
0x5c, 0x80, 0x4d, 0x09, 0x56, 0xa6, 0x6c, 0x65, 0x13, 0x6a, 0xa1, 0xcd, 0x7b, 0x26, 0xf5, 0x2d,
|
||||||
0xf5, 0x2c, 0x23, 0x31, 0x72, 0x19, 0xf2, 0x0f, 0x13, 0x70, 0x9e, 0x8b, 0xaa, 0x1b, 0xef, 0xf7,
|
0x43, 0x1a, 0xba, 0x0c, 0xe5, 0x47, 0x12, 0x9c, 0xe7, 0xa2, 0xea, 0xe6, 0xfb, 0xdd, 0xb6, 0xa9,
|
||||||
0x3a, 0x86, 0xaa, 0x3d, 0x77, 0x4d, 0xca, 0x9f, 0x24, 0x40, 0x0a, 0x2d, 0xea, 0x2c, 0x9c, 0xd6,
|
0xe9, 0xcf, 0x5d, 0x93, 0xca, 0x27, 0x12, 0xc8, 0x91, 0x45, 0x9d, 0x85, 0xd3, 0xfa, 0x74, 0x95,
|
||||||
0xa3, 0xab, 0xe4, 0x68, 0x93, 0x1d, 0xdf, 0x5b, 0x7f, 0x90, 0x80, 0x73, 0x7c, 0x43, 0xcd, 0xde,
|
0x1a, 0x6e, 0xb2, 0xe3, 0x7b, 0xeb, 0x0f, 0x25, 0x38, 0xc7, 0x37, 0xd4, 0xe8, 0xee, 0x9b, 0xcf,
|
||||||
0xbe, 0xf1, 0xfc, 0x35, 0xfc, 0xa6, 0x03, 0xb2, 0x6c, 0x3d, 0x91, 0xee, 0x33, 0x5a, 0x25, 0x24,
|
0x5f, 0xc3, 0x6f, 0xba, 0x20, 0xcb, 0xd6, 0x13, 0xeb, 0x3e, 0xc3, 0x55, 0x42, 0xb2, 0xb8, 0x08,
|
||||||
0x8b, 0x8b, 0x30, 0xf4, 0xd5, 0x0e, 0xcf, 0x71, 0x6b, 0x3f, 0x4e, 0x38, 0xc1, 0xe1, 0x2f, 0x39,
|
0xc3, 0x40, 0xed, 0xf0, 0x1c, 0xb7, 0xf6, 0x13, 0xc9, 0x0d, 0x8e, 0x60, 0xc9, 0x71, 0xba, 0xae,
|
||||||
0x4e, 0xd7, 0x75, 0x02, 0xce, 0x90, 0x1c, 0xdf, 0x19, 0xbe, 0x9f, 0x84, 0x79, 0x52, 0x34, 0xf0,
|
0x13, 0x72, 0x86, 0xd4, 0xe8, 0xce, 0xf0, 0x51, 0x0a, 0xe6, 0x48, 0xd1, 0xc0, 0x17, 0x69, 0x9f,
|
||||||
0x45, 0x5a, 0x67, 0xa1, 0xb2, 0x79, 0xc8, 0xf6, 0x4d, 0xbc, 0xaf, 0x1f, 0x71, 0xa5, 0xf1, 0x3b,
|
0x85, 0xca, 0xe6, 0x20, 0xd7, 0xb3, 0xf0, 0xbe, 0x71, 0xc4, 0x95, 0xc6, 0xef, 0xd0, 0x12, 0x94,
|
||||||
0xb4, 0x0c, 0x45, 0xcb, 0x56, 0x4d, 0xbb, 0xa5, 0xee, 0x13, 0x0b, 0x53, 0x17, 0x56, 0x80, 0x92,
|
0x6c, 0x47, 0xb3, 0x9c, 0xa6, 0xb6, 0x4f, 0x2c, 0x4c, 0x5d, 0x58, 0x05, 0x4a, 0x5a, 0x23, 0x14,
|
||||||
0xd6, 0x09, 0x85, 0x14, 0x11, 0xb8, 0xa7, 0xb5, 0xf6, 0xf0, 0x3e, 0xa9, 0x61, 0xd2, 0xac, 0x88,
|
0x74, 0x19, 0x00, 0x77, 0xf5, 0xe6, 0x1e, 0xde, 0x27, 0x35, 0x4c, 0x86, 0xee, 0x2a, 0x55, 0x93,
|
||||||
0xc0, 0x3d, 0x6d, 0x83, 0x12, 0x48, 0x01, 0x65, 0x62, 0x52, 0x62, 0xe9, 0xef, 0xb1, 0xec, 0x95,
|
0xd4, 0x22, 0xee, 0xea, 0xeb, 0x94, 0x48, 0x8a, 0x28, 0x0b, 0x93, 0x32, 0xcb, 0x78, 0x8f, 0x65,
|
||||||
0x57, 0x5c, 0x82, 0x5b, 0x74, 0x65, 0xbd, 0x45, 0xd7, 0x12, 0x00, 0xd9, 0x45, 0x6b, 0xbf, 0xa3,
|
0xb0, 0x82, 0xea, 0x11, 0xbc, 0xc2, 0x2b, 0xe7, 0x2f, 0xbc, 0x16, 0x01, 0xc8, 0x4e, 0x9a, 0xfb,
|
||||||
0x1e, 0x58, 0xf4, 0x45, 0x2b, 0xa7, 0x14, 0x08, 0xe5, 0x4d, 0x42, 0xa0, 0xe9, 0xc9, 0xaf, 0x0e,
|
0x6d, 0xed, 0xc0, 0xa6, 0x2f, 0x5b, 0x79, 0xb5, 0x48, 0x28, 0x6f, 0x12, 0x02, 0x4d, 0x51, 0x41,
|
||||||
0xd7, 0x5c, 0x37, 0xfd, 0xb5, 0xd7, 0x0b, 0xae, 0x3a, 0x62, 0x66, 0xac, 0x8e, 0xa8, 0xc4, 0x24,
|
0x95, 0x78, 0x26, 0xbb, 0x19, 0xac, 0xbf, 0x5e, 0xf0, 0x54, 0x92, 0x30, 0x63, 0x65, 0x48, 0x35,
|
||||||
0x0c, 0x69, 0xf1, 0x32, 0x47, 0x7d, 0x2a, 0xe1, 0xf1, 0xa9, 0xc9, 0xd0, 0x60, 0x11, 0x0a, 0xba,
|
0x26, 0x63, 0xc8, 0x88, 0x17, 0x3a, 0xea, 0x57, 0x92, 0xcf, 0xaf, 0xc6, 0x43, 0x84, 0x05, 0x28,
|
||||||
0xd5, 0xe2, 0x5a, 0x4e, 0xd1, 0x47, 0xe4, 0x75, 0x6b, 0x87, 0xde, 0xcb, 0xdf, 0xa3, 0x4e, 0x18,
|
0x1a, 0x76, 0x93, 0x6b, 0x3a, 0x4d, 0x1f, 0x51, 0x30, 0xec, 0x1d, 0x7a, 0xaf, 0xfc, 0x80, 0x3a,
|
||||||
0x51, 0xea, 0x1d, 0xcb, 0xca, 0xcb, 0x50, 0x64, 0x76, 0x6d, 0x79, 0x8a, 0x3e, 0x60, 0xa4, 0xed,
|
0x62, 0x4c, 0xb9, 0x77, 0x2c, 0x4b, 0x2f, 0x41, 0x89, 0xd9, 0xb6, 0xe9, 0x2b, 0xfc, 0x80, 0x91,
|
||||||
0x31, 0x4a, 0xbf, 0x45, 0x82, 0xf1, 0x51, 0x45, 0xdf, 0xbd, 0x8e, 0x26, 0x6f, 0x02, 0xda, 0x31,
|
0xb6, 0x47, 0x28, 0xff, 0x16, 0x08, 0xce, 0xc7, 0x15, 0x7e, 0xf7, 0xda, 0xba, 0xb2, 0x01, 0x68,
|
||||||
0x8d, 0x6f, 0xe0, 0xb6, 0x17, 0x9a, 0x26, 0x5e, 0xa3, 0xfc, 0x1a, 0xcc, 0xfa, 0xc4, 0xf0, 0xea,
|
0xc7, 0x32, 0xbf, 0x85, 0x5b, 0x7e, 0x78, 0x1a, 0x7b, 0x8d, 0xca, 0x6b, 0x30, 0x13, 0x10, 0xc3,
|
||||||
0xf9, 0x32, 0x94, 0xfa, 0x8c, 0xdc, 0xb2, 0xd4, 0x8e, 0x70, 0xd3, 0x22, 0xa7, 0xed, 0xaa, 0x1d,
|
0x2b, 0xe8, 0xcb, 0x50, 0xee, 0x31, 0x72, 0xd3, 0xd6, 0xda, 0xc2, 0x55, 0x4b, 0x9c, 0xb6, 0xab,
|
||||||
0x5b, 0xfe, 0x6e, 0x0e, 0xb2, 0xf7, 0xf6, 0xc8, 0x6d, 0xac, 0x3b, 0x5f, 0x83, 0x19, 0xb7, 0x82,
|
0xb5, 0x1d, 0xe5, 0xfb, 0x79, 0xc8, 0xdd, 0xdb, 0x23, 0xb7, 0x89, 0x2e, 0x7d, 0x0d, 0xa6, 0xbc,
|
||||||
0xf2, 0x60, 0xc1, 0xb4, 0x43, 0xdd, 0xe1, 0xa0, 0xf0, 0x1e, 0x36, 0x2d, 0xb7, 0xb8, 0x17, 0xb7,
|
0x2a, 0xca, 0x87, 0x07, 0x93, 0x2e, 0x75, 0x87, 0x03, 0xc3, 0x7b, 0xd8, 0xb2, 0xbd, 0x02, 0x5f,
|
||||||
0x64, 0x3b, 0x96, 0xad, 0xda, 0x03, 0x8b, 0xba, 0xf4, 0x8c, 0x77, 0x3b, 0xec, 0xd1, 0xab, 0xbb,
|
0xdc, 0x92, 0xed, 0xd8, 0x8e, 0xe6, 0xf4, 0x6d, 0xea, 0xd6, 0x53, 0xfe, 0xed, 0xb0, 0x47, 0xaf,
|
||||||
0x74, 0x58, 0xe1, 0x6c, 0xe8, 0x65, 0x28, 0x58, 0xb6, 0x89, 0xd5, 0x2e, 0x51, 0x68, 0x86, 0x06,
|
0xec, 0xd2, 0x61, 0x95, 0xb3, 0xa1, 0x97, 0xa1, 0x68, 0x3b, 0x16, 0xd6, 0x3a, 0x44, 0xa1, 0x59,
|
||||||
0x77, 0x85, 0x07, 0x77, 0x7e, 0x97, 0x0e, 0x34, 0xeb, 0x4a, 0x9e, 0xb1, 0x34, 0xb5, 0x40, 0x1f,
|
0x1a, 0x0a, 0x55, 0x1e, 0xe0, 0x85, 0x5d, 0x3a, 0xd0, 0xa8, 0xab, 0x05, 0xc6, 0xd2, 0xd0, 0x43,
|
||||||
0x20, 0x7b, 0xbc, 0x16, 0xcc, 0x3a, 0x79, 0x26, 0x79, 0x3a, 0x91, 0x91, 0x9b, 0x40, 0x46, 0x9e,
|
0xbd, 0x80, 0xdc, 0xf1, 0xda, 0x30, 0x6b, 0xe4, 0x99, 0xe4, 0xe9, 0x44, 0x46, 0x7e, 0x0c, 0x19,
|
||||||
0x4d, 0x5b, 0x27, 0x25, 0x38, 0xab, 0xfc, 0x30, 0x95, 0x91, 0x9f, 0x64, 0x1d, 0x7c, 0xde, 0xba,
|
0x05, 0x36, 0x6d, 0x8d, 0x94, 0xe1, 0xac, 0xfa, 0xc3, 0x54, 0x46, 0x61, 0x9c, 0x75, 0xf0, 0x79,
|
||||||
0x8d, 0x6e, 0x43, 0xcd, 0xd5, 0x36, 0xd1, 0x93, 0xa6, 0xda, 0x6a, 0xab, 0x67, 0xf4, 0xda, 0xb8,
|
0x6b, 0x0e, 0xba, 0x0d, 0x35, 0x4f, 0xdb, 0x44, 0x4f, 0xba, 0xe6, 0x68, 0xcd, 0xae, 0xd9, 0x6d,
|
||||||
0x56, 0xa0, 0xaa, 0x98, 0xe6, 0xaa, 0xc8, 0x6c, 0x13, 0xa2, 0x32, 0xef, 0xb0, 0x6f, 0x71, 0x6e,
|
0xe1, 0x5a, 0x91, 0xaa, 0x62, 0x92, 0xab, 0x22, 0xbb, 0x4d, 0x88, 0xea, 0x9c, 0xcb, 0xbe, 0xc5,
|
||||||
0x4a, 0x47, 0x2f, 0x03, 0x0a, 0x0b, 0xaa, 0x01, 0x35, 0x5d, 0x35, 0x34, 0x07, 0xbd, 0x04, 0x68,
|
0xb9, 0x29, 0x1d, 0xbd, 0x0c, 0x28, 0x2a, 0xa8, 0x06, 0xd4, 0x74, 0xd3, 0x91, 0x39, 0xe8, 0x25,
|
||||||
0x5f, 0x3f, 0x0a, 0xd6, 0xc8, 0x45, 0x0a, 0xef, 0x15, 0x3a, 0xe2, 0x2d, 0x8e, 0x1b, 0x50, 0x0d,
|
0x40, 0xfb, 0xc6, 0x51, 0xb8, 0x4e, 0x2e, 0x51, 0x88, 0xaf, 0xd2, 0x11, 0x7f, 0x81, 0xbc, 0x09,
|
||||||
0x37, 0x19, 0x4a, 0xa3, 0xab, 0xf3, 0x8a, 0x19, 0xec, 0x2e, 0x3c, 0x80, 0x73, 0xd1, 0x5d, 0x85,
|
0xd3, 0xd1, 0x46, 0x43, 0x79, 0x78, 0x85, 0x5e, 0xb5, 0xc2, 0x1d, 0x86, 0x07, 0x70, 0x2e, 0xbe,
|
||||||
0xe9, 0x31, 0xbb, 0x0a, 0x73, 0x38, 0xa6, 0x9d, 0x60, 0x1b, 0xb6, 0xda, 0x61, 0xdb, 0x98, 0xa1,
|
0xb3, 0x30, 0x39, 0x62, 0x67, 0x61, 0x16, 0x27, 0xb4, 0x14, 0x1c, 0xd3, 0xd1, 0xda, 0x6c, 0x1b,
|
||||||
0xdb, 0x28, 0x50, 0x0a, 0x5d, 0xff, 0x32, 0x14, 0xf5, 0x5e, 0x47, 0xef, 0x61, 0x36, 0x5e, 0xa6,
|
0x53, 0x74, 0x1b, 0x45, 0x4a, 0xa1, 0xeb, 0x5f, 0x82, 0x92, 0xd1, 0x6d, 0x1b, 0x5d, 0xcc, 0xc6,
|
||||||
0xe3, 0xc0, 0x48, 0x82, 0xc1, 0xc4, 0x5d, 0xc3, 0xe6, 0x0c, 0x15, 0xc6, 0xc0, 0x48, 0x84, 0x41,
|
0x2b, 0x74, 0x1c, 0x18, 0x49, 0x30, 0x58, 0xb8, 0x63, 0x3a, 0x9c, 0xa1, 0xca, 0x18, 0x18, 0x89,
|
||||||
0x7e, 0x1b, 0xb2, 0xcc, 0x6b, 0x51, 0x11, 0x72, 0xcd, 0xed, 0x77, 0xd6, 0xef, 0x36, 0xeb, 0x95,
|
0x30, 0x28, 0x6f, 0x43, 0x8e, 0x79, 0x2d, 0x2a, 0x41, 0xbe, 0xb1, 0xfd, 0xce, 0xda, 0xdd, 0x46,
|
||||||
0x29, 0x34, 0x0d, 0x85, 0x07, 0x3b, 0x77, 0xef, 0xad, 0xd7, 0x9b, 0xdb, 0xb7, 0x2b, 0x09, 0x34,
|
0xbd, 0x3a, 0x81, 0x26, 0xa1, 0xf8, 0x60, 0xe7, 0xee, 0xbd, 0xb5, 0x7a, 0x63, 0xfb, 0x76, 0x55,
|
||||||
0x03, 0x70, 0xeb, 0xde, 0xd6, 0x56, 0xf3, 0xfe, 0x7d, 0x72, 0x9f, 0x24, 0xc3, 0xfc, 0x7e, 0xb3,
|
0x42, 0x53, 0x00, 0xb7, 0xee, 0x6d, 0x6d, 0x35, 0xee, 0xdf, 0x27, 0xf7, 0x29, 0x32, 0xcc, 0xef,
|
||||||
0x5e, 0x49, 0xa1, 0x12, 0xe4, 0xeb, 0x9b, 0x77, 0x37, 0xe9, 0x60, 0x5a, 0xfe, 0x30, 0x05, 0x88,
|
0x37, 0xea, 0xd5, 0x34, 0x2a, 0x43, 0xa1, 0xbe, 0x71, 0x77, 0x83, 0x0e, 0x66, 0x94, 0x0f, 0xd3,
|
||||||
0x05, 0xc4, 0x06, 0x3e, 0xd0, 0x7b, 0x27, 0x79, 0x2d, 0x3f, 0x9b, 0x40, 0xf6, 0x3b, 0x78, 0xfa,
|
0x80, 0x58, 0x40, 0xac, 0xe3, 0x03, 0xa3, 0x7b, 0x92, 0x57, 0xf3, 0xb3, 0x09, 0xe4, 0xa0, 0x83,
|
||||||
0x78, 0x0e, 0x1e, 0xe9, 0x3a, 0xb9, 0x53, 0x75, 0x9d, 0xfc, 0x49, 0x5c, 0x47, 0xfe, 0x55, 0x12,
|
0x67, 0x8e, 0xe7, 0xe0, 0xb1, 0xae, 0x93, 0x3f, 0x55, 0xd7, 0x29, 0x9c, 0xc4, 0x75, 0x94, 0x5f,
|
||||||
0x66, 0x7d, 0x66, 0xe0, 0x68, 0x7a, 0x66, 0x6a, 0xf5, 0xc1, 0x5d, 0x7a, 0x24, 0xdc, 0x45, 0x2a,
|
0xa7, 0x60, 0x26, 0x60, 0x06, 0x8e, 0xa6, 0x67, 0xa6, 0xd6, 0x00, 0xdc, 0x65, 0x86, 0xc2, 0x5d,
|
||||||
0x30, 0x73, 0xaa, 0x0a, 0xcc, 0x9e, 0x48, 0x81, 0x7f, 0x4b, 0x08, 0x05, 0xfa, 0xde, 0x0e, 0x27,
|
0xac, 0x02, 0xb3, 0xa7, 0xaa, 0xc0, 0xdc, 0x89, 0x14, 0xf8, 0x77, 0x49, 0x28, 0x30, 0xf0, 0x86,
|
||||||
0x77, 0x64, 0x9f, 0x62, 0x12, 0x23, 0x15, 0x33, 0x0c, 0x3a, 0x93, 0x27, 0x87, 0xce, 0x54, 0x0c,
|
0x38, 0xbe, 0x23, 0x07, 0x14, 0x23, 0x0d, 0x55, 0xcc, 0x20, 0xe8, 0x4c, 0x9d, 0x1c, 0x3a, 0xd3,
|
||||||
0x74, 0xca, 0xf3, 0x30, 0xe7, 0xdf, 0x2e, 0x6f, 0xea, 0xfc, 0x28, 0x01, 0x15, 0x36, 0x70, 0x92,
|
0x09, 0xd0, 0xa9, 0xcc, 0xc1, 0x6c, 0x70, 0xbb, 0xbc, 0xb1, 0xf3, 0x63, 0x09, 0xaa, 0x6c, 0xe0,
|
||||||
0x96, 0xe3, 0x59, 0xb9, 0x9d, 0xfc, 0x3a, 0x54, 0x3d, 0xab, 0x73, 0xfb, 0x96, 0x06, 0x25, 0x86,
|
0x24, 0x6d, 0xc7, 0xb3, 0x72, 0x3b, 0xe5, 0x75, 0x98, 0xf6, 0xad, 0xce, 0xeb, 0x5d, 0x9a, 0x94,
|
||||||
0xfb, 0x96, 0x8c, 0x59, 0xe1, 0xe3, 0xf2, 0x4f, 0x93, 0x62, 0xfe, 0x49, 0x7b, 0x88, 0x91, 0xdb,
|
0x18, 0xed, 0x5d, 0x32, 0x66, 0x95, 0x8f, 0x2b, 0x3f, 0x4b, 0x89, 0xf9, 0x27, 0xed, 0x23, 0xc6,
|
||||||
0xfb, 0x1f, 0xa8, 0x78, 0xb6, 0xe7, 0x2d, 0xa7, 0xcb, 0xee, 0x06, 0x59, 0x5d, 0xed, 0x63, 0xe5,
|
0x6e, 0xef, 0xff, 0xa0, 0xea, 0xdb, 0x9e, 0xbf, 0xa4, 0xae, 0x78, 0x1b, 0x64, 0xb5, 0x75, 0x80,
|
||||||
0x0d, 0xc9, 0x54, 0x80, 0xf5, 0x16, 0xeb, 0x4c, 0xfa, 0x4a, 0xe8, 0x74, 0x6c, 0x09, 0x9d, 0xf1,
|
0x95, 0x37, 0x25, 0xd3, 0x21, 0xd6, 0x5b, 0xac, 0x3b, 0x19, 0x28, 0xa1, 0x33, 0x89, 0x25, 0x74,
|
||||||
0x96, 0xd0, 0x4d, 0x28, 0xb3, 0x2d, 0xb7, 0xf4, 0x5e, 0xbb, 0x33, 0xd0, 0xb0, 0x1b, 0x1f, 0x01,
|
0xd6, 0x5f, 0x42, 0x37, 0xa0, 0xc2, 0xb6, 0xdc, 0x34, 0xba, 0xad, 0x76, 0x5f, 0xc7, 0x5e, 0x7c,
|
||||||
0xdd, 0x88, 0x6e, 0x64, 0x93, 0xf3, 0x29, 0x33, 0x6c, 0xa2, 0xb8, 0x97, 0x1f, 0x09, 0x80, 0x1f,
|
0x84, 0x74, 0x23, 0x3a, 0x92, 0x0d, 0xce, 0xa7, 0x4e, 0xb1, 0x89, 0xe2, 0x5e, 0x79, 0x24, 0x00,
|
||||||
0xb3, 0xc9, 0xe9, 0x17, 0x3b, 0xac, 0xc9, 0xf9, 0xeb, 0x14, 0xcc, 0xf8, 0xb9, 0x23, 0x1c, 0x24,
|
0x7e, 0xc4, 0x46, 0x67, 0x50, 0xec, 0xa0, 0x46, 0xe7, 0x6f, 0xd2, 0x30, 0x15, 0xe4, 0x8e, 0x71,
|
||||||
0x31, 0xc2, 0x41, 0x92, 0x71, 0x75, 0x5b, 0x6a, 0xbc, 0xba, 0xcd, 0x5f, 0x88, 0xa5, 0x4f, 0xa1,
|
0x10, 0x69, 0x88, 0x83, 0xa4, 0x92, 0xea, 0xb6, 0xf4, 0x68, 0x75, 0x5b, 0xb0, 0x10, 0xcb, 0x9c,
|
||||||
0x10, 0xcb, 0x9c, 0x42, 0x21, 0x96, 0x3d, 0xfd, 0x42, 0x2c, 0x77, 0x72, 0x34, 0xc9, 0xc7, 0xa1,
|
0x42, 0x21, 0x96, 0x3d, 0x85, 0x42, 0x2c, 0x77, 0xfa, 0x85, 0x58, 0xfe, 0xe4, 0x68, 0x52, 0x48,
|
||||||
0xc9, 0xff, 0xc1, 0x7c, 0xb4, 0x37, 0x21, 0x09, 0xf2, 0xce, 0xf4, 0x04, 0x7b, 0xe7, 0x11, 0xf7,
|
0x42, 0x93, 0x2f, 0xc0, 0x5c, 0xbc, 0x37, 0x21, 0x19, 0x0a, 0xee, 0x74, 0x89, 0xbd, 0xf3, 0x88,
|
||||||
0xf2, 0xc7, 0x09, 0xa8, 0x79, 0x92, 0xd6, 0x09, 0xcf, 0x12, 0xce, 0x0c, 0x73, 0xde, 0x82, 0xf3,
|
0x7b, 0xe5, 0x63, 0x09, 0x6a, 0xbe, 0xa4, 0x75, 0xc2, 0xf3, 0x84, 0x33, 0xc3, 0x9c, 0xb7, 0xe0,
|
||||||
0x11, 0xab, 0xe4, 0x71, 0x30, 0x19, 0xdc, 0xcb, 0xdf, 0x12, 0xb2, 0xde, 0xd4, 0x7b, 0xba, 0x75,
|
0x7c, 0xcc, 0x2a, 0x79, 0x1c, 0x8c, 0x07, 0xf7, 0xca, 0x77, 0x84, 0xac, 0x37, 0x8d, 0xae, 0x61,
|
||||||
0x78, 0xc2, 0x2d, 0x4f, 0xf8, 0xf0, 0x0b, 0x20, 0x45, 0x3d, 0x9c, 0x23, 0xff, 0xdf, 0x93, 0x50,
|
0x1f, 0x9e, 0x70, 0xcb, 0x63, 0x3e, 0xfc, 0x02, 0xc8, 0x71, 0x0f, 0xe7, 0xc8, 0xff, 0x8f, 0x14,
|
||||||
0xdc, 0x55, 0x6d, 0x31, 0xef, 0xec, 0x4a, 0x87, 0x13, 0xb5, 0xc7, 0x9b, 0x30, 0x4d, 0xc3, 0x8e,
|
0x94, 0x76, 0x35, 0x47, 0xcc, 0x3b, 0xbb, 0xd2, 0xe1, 0x44, 0x2d, 0xf2, 0x06, 0x4c, 0xd2, 0xb0,
|
||||||
0x24, 0x7f, 0x4d, 0xb5, 0xf1, 0x44, 0xd1, 0x56, 0x12, 0x53, 0xeb, 0xaa, 0x8d, 0xd1, 0x16, 0x94,
|
0x23, 0xc9, 0x5f, 0xd7, 0x1c, 0x3c, 0x56, 0xb4, 0x95, 0xc5, 0xd4, 0xba, 0xe6, 0x60, 0xb4, 0x05,
|
||||||
0xdd, 0xa6, 0x37, 0x13, 0x36, 0x49, 0xd8, 0xcd, 0xb8, 0x93, 0xa9, 0xb8, 0xeb, 0x30, 0x6b, 0xa9,
|
0x15, 0xaf, 0xf1, 0xcd, 0x84, 0x8d, 0x13, 0x76, 0x53, 0xde, 0x64, 0x2a, 0xee, 0x3a, 0xcc, 0xd8,
|
||||||
0x36, 0xee, 0x74, 0x74, 0x5a, 0x80, 0x1f, 0xf4, 0x54, 0x7b, 0x60, 0xf2, 0xf7, 0x1f, 0x05, 0x39,
|
0x9a, 0x83, 0xdb, 0x6d, 0x83, 0x16, 0xe0, 0x07, 0x5d, 0xcd, 0xe9, 0x5b, 0xfc, 0xfd, 0x47, 0x45,
|
||||||
0x43, 0xbb, 0x62, 0x44, 0xfe, 0x4b, 0x12, 0x72, 0xfc, 0xfd, 0x64, 0xd2, 0xaa, 0xe1, 0xff, 0x21,
|
0xee, 0xd0, 0xae, 0x18, 0x51, 0xfe, 0x9a, 0x82, 0x3c, 0x7f, 0x3f, 0x19, 0xb7, 0x6a, 0xf8, 0x22,
|
||||||
0xdf, 0x37, 0x2c, 0xdd, 0x16, 0x00, 0x58, 0x5c, 0x3b, 0xef, 0xfa, 0x0a, 0x97, 0xb9, 0xc3, 0x19,
|
0x14, 0x7a, 0xa6, 0x6d, 0x38, 0x02, 0x00, 0x4b, 0xab, 0xe7, 0x3d, 0x5f, 0xe1, 0x32, 0x77, 0x38,
|
||||||
0x14, 0x87, 0x15, 0xbd, 0x0e, 0xb3, 0xae, 0xe9, 0x9e, 0xe0, 0xa7, 0x1c, 0x19, 0x52, 0x51, 0xc8,
|
0x83, 0xea, 0xb2, 0xa2, 0xd7, 0x61, 0xc6, 0x33, 0xdd, 0x13, 0xfc, 0x94, 0x23, 0x43, 0x3a, 0x0e,
|
||||||
0xe0, 0x46, 0xf9, 0x1d, 0xfc, 0x94, 0x81, 0xc2, 0x15, 0x98, 0xf6, 0x4d, 0xe7, 0xdd, 0x9e, 0x92,
|
0x19, 0xbc, 0x28, 0xbf, 0x83, 0x9f, 0x32, 0x50, 0xb8, 0x02, 0x93, 0x81, 0xe9, 0xac, 0xee, 0x53,
|
||||||
0x97, 0x13, 0xad, 0xc2, 0x2c, 0x79, 0xfb, 0xf0, 0x1c, 0x60, 0xd0, 0xd8, 0x67, 0x07, 0x17, 0x55,
|
0xcb, 0x7e, 0x4e, 0xb4, 0x02, 0x33, 0xe4, 0xed, 0xc3, 0x77, 0x88, 0x41, 0x63, 0x9f, 0x1d, 0x5e,
|
||||||
0x32, 0xe4, 0x9c, 0x5c, 0xd4, 0xc9, 0x3b, 0xdc, 0x9a, 0x53, 0xcf, 0x61, 0xad, 0xc5, 0xdf, 0x6f,
|
0x4c, 0x93, 0x21, 0xf7, 0xf4, 0xa2, 0x4e, 0xde, 0xe1, 0x56, 0xdd, 0x7a, 0x0e, 0xeb, 0x4d, 0xfe,
|
||||||
0xe8, 0x0c, 0x76, 0x9c, 0xea, 0x2e, 0xb8, 0x49, 0xc7, 0xe8, 0x9c, 0x17, 0x21, 0x4b, 0x4f, 0x0d,
|
0x7e, 0x43, 0x67, 0xb0, 0x23, 0x55, 0x6f, 0xc1, 0x0d, 0x3a, 0x46, 0xe7, 0xbc, 0x08, 0x39, 0x7a,
|
||||||
0xac, 0x5a, 0x8e, 0x66, 0x9f, 0xb2, 0xbb, 0x79, 0xda, 0x47, 0x53, 0xf8, 0xb0, 0xdc, 0x80, 0x0c,
|
0x72, 0x60, 0xd7, 0xf2, 0x34, 0xfb, 0x54, 0xbc, 0xcd, 0xd3, 0x5e, 0x9a, 0xca, 0x87, 0x95, 0x4d,
|
||||||
0x25, 0xa0, 0x45, 0x28, 0xb0, 0x73, 0x86, 0xde, 0xa0, 0x4b, 0xf5, 0x9b, 0x51, 0xf2, 0x94, 0xb0,
|
0xc8, 0x52, 0x02, 0x5a, 0x80, 0x22, 0x3b, 0x6b, 0xe8, 0xf6, 0x3b, 0x54, 0xbf, 0x59, 0xb5, 0x40,
|
||||||
0x3d, 0xe8, 0x22, 0x19, 0xd2, 0x3d, 0x43, 0x13, 0xf5, 0xd6, 0x0c, 0xd7, 0x43, 0x76, 0xdb, 0xd0,
|
0x09, 0xdb, 0xfd, 0x0e, 0x52, 0x20, 0xd3, 0x35, 0x75, 0x51, 0x6f, 0x4d, 0x71, 0x3d, 0xe4, 0xb6,
|
||||||
0x70, 0xb3, 0xae, 0xd0, 0x31, 0xb9, 0x01, 0xe5, 0x80, 0x5e, 0xc9, 0xeb, 0x56, 0x5f, 0x35, 0x6d,
|
0x4d, 0x1d, 0x37, 0xea, 0x2a, 0x1d, 0x53, 0x36, 0xa1, 0x12, 0xd2, 0x2b, 0x79, 0xdd, 0xea, 0x69,
|
||||||
0x22, 0x72, 0x8f, 0xf7, 0xce, 0x33, 0x0a, 0x6d, 0xab, 0x6c, 0x53, 0x0a, 0x49, 0xcd, 0x7a, 0x4f,
|
0x96, 0x43, 0x44, 0xee, 0xf1, 0xfe, 0x79, 0x56, 0xa5, 0x6d, 0x95, 0x6d, 0x4a, 0x21, 0xa9, 0xd9,
|
||||||
0xc3, 0x47, 0xe2, 0x48, 0x91, 0xde, 0xc8, 0x7f, 0x48, 0xc0, 0x2c, 0x17, 0x75, 0xb2, 0x57, 0xa6,
|
0xe8, 0xea, 0xf8, 0x48, 0x1c, 0x2b, 0xd2, 0x1b, 0xe5, 0x8f, 0x12, 0xcc, 0x70, 0x51, 0x27, 0x7b,
|
||||||
0x67, 0xe3, 0x33, 0x2f, 0x40, 0xb9, 0xab, 0x1e, 0xb5, 0xe8, 0x11, 0x03, 0x6b, 0x80, 0xf2, 0xfe,
|
0x65, 0x7a, 0x36, 0x3e, 0xf3, 0x02, 0x54, 0x3a, 0xda, 0x51, 0x93, 0x1e, 0x33, 0xb0, 0x26, 0x28,
|
||||||
0xe9, 0x74, 0x57, 0x3d, 0x72, 0xfb, 0x9d, 0xf2, 0xef, 0x12, 0x30, 0xe7, 0xdf, 0x16, 0x47, 0xc8,
|
0xef, 0xa1, 0x4e, 0x76, 0xb4, 0x23, 0xaf, 0xe7, 0xa9, 0xfc, 0x5e, 0x82, 0xd9, 0xe0, 0xb6, 0x38,
|
||||||
0x57, 0x00, 0xc4, 0xeb, 0xb9, 0xb3, 0xce, 0x2a, 0x5f, 0x67, 0x41, 0xf4, 0x94, 0xeb, 0x4a, 0x81,
|
0x42, 0xbe, 0x02, 0x20, 0x5e, 0xcf, 0xdd, 0x75, 0x4e, 0xf3, 0x75, 0x16, 0x45, 0x5f, 0xb9, 0xae,
|
||||||
0x33, 0x35, 0xa3, 0x7b, 0xae, 0xc9, 0xd3, 0xe8, 0xb9, 0x4e, 0xd0, 0x80, 0xff, 0x63, 0xd2, 0xd9,
|
0x16, 0x39, 0x53, 0x23, 0xbe, 0xef, 0x9a, 0x3a, 0x8d, 0xbe, 0xeb, 0x18, 0x4d, 0xf8, 0x3f, 0xa5,
|
||||||
0xce, 0x09, 0x5f, 0x08, 0x26, 0xdf, 0x7f, 0x4c, 0x98, 0x26, 0x8f, 0x1b, 0xa6, 0xa9, 0xf1, 0xc3,
|
0xdc, 0xed, 0x9c, 0xf0, 0x85, 0x60, 0xfc, 0xfd, 0x27, 0x84, 0x69, 0xea, 0xb8, 0x61, 0x9a, 0x1e,
|
||||||
0x34, 0x1d, 0x17, 0xa6, 0xb7, 0x61, 0x7a, 0xd0, 0xef, 0x18, 0xaa, 0xd6, 0x32, 0xb1, 0x35, 0xe8,
|
0x3d, 0x4c, 0x33, 0x49, 0x61, 0x7a, 0x1b, 0x26, 0xfb, 0xbd, 0xb6, 0xa9, 0xe9, 0x4d, 0x0b, 0xdb,
|
||||||
0xd8, 0xfc, 0xec, 0x49, 0x0e, 0xbb, 0x10, 0x51, 0xea, 0x83, 0x3e, 0x3f, 0x82, 0x19, 0x74, 0x6c,
|
0xfd, 0xb6, 0xc3, 0xcf, 0x9f, 0x94, 0xa8, 0x0b, 0x11, 0xa5, 0x3e, 0xe8, 0xf1, 0x63, 0x98, 0x7e,
|
||||||
0xa5, 0x34, 0xf0, 0xdc, 0xc9, 0xdf, 0x71, 0xbb, 0xed, 0x21, 0xd6, 0xe1, 0x61, 0xfa, 0x22, 0xe4,
|
0xdb, 0x51, 0xcb, 0x7d, 0xdf, 0x9d, 0xf2, 0x3d, 0xaf, 0xe3, 0x1e, 0x61, 0x1d, 0x1c, 0xa6, 0x2f,
|
||||||
0xe8, 0x29, 0xb1, 0x73, 0x54, 0x18, 0x8c, 0xd4, 0x2c, 0x19, 0x6e, 0x6a, 0xe8, 0x1a, 0xa4, 0x0f,
|
0x42, 0x9e, 0x9e, 0x14, 0xbb, 0xc7, 0x85, 0xe1, 0x48, 0xcd, 0x91, 0xe1, 0x86, 0x8e, 0xae, 0x41,
|
||||||
0x55, 0xeb, 0x90, 0x7f, 0xd8, 0x54, 0x15, 0xc7, 0x63, 0xf4, 0x71, 0x0d, 0xd5, 0x3a, 0x54, 0xe8,
|
0xe6, 0x50, 0xb3, 0x0f, 0xf9, 0xc7, 0x4d, 0xd3, 0xe2, 0x88, 0x8c, 0x3e, 0x6e, 0x53, 0xb3, 0x0f,
|
||||||
0xb0, 0xfc, 0xef, 0x24, 0x94, 0x48, 0xc2, 0x13, 0x26, 0x40, 0x6b, 0xc1, 0x80, 0x2a, 0xae, 0x9d,
|
0x55, 0x3a, 0xac, 0xfc, 0x27, 0x05, 0x65, 0x92, 0xf0, 0x84, 0x09, 0xd0, 0x6a, 0x38, 0xa0, 0x4a,
|
||||||
0xf3, 0xec, 0xcf, 0xcd, 0x8d, 0x9e, 0xa8, 0x0a, 0x80, 0x40, 0x32, 0x1e, 0x04, 0x52, 0x1e, 0x10,
|
0xab, 0xe7, 0x7c, 0xfb, 0xf3, 0x72, 0xa3, 0x2f, 0xaa, 0x42, 0x20, 0x90, 0x4a, 0x06, 0x81, 0xb4,
|
||||||
0x08, 0x1f, 0x7e, 0x66, 0xc6, 0x38, 0xfc, 0x7c, 0x1b, 0xce, 0x39, 0x27, 0x80, 0x9e, 0x78, 0x24,
|
0x0f, 0x04, 0xa2, 0x07, 0xa0, 0xd9, 0x11, 0x0e, 0x40, 0xdf, 0x86, 0x73, 0xee, 0x29, 0xa0, 0x2f,
|
||||||
0xa5, 0xfd, 0x18, 0xc1, 0x31, 0x2b, 0xe6, 0xba, 0x34, 0x2b, 0x9c, 0x4e, 0x73, 0xc7, 0x4e, 0xa7,
|
0x1e, 0x49, 0x69, 0x3f, 0x42, 0x70, 0xcc, 0x88, 0xb9, 0x1e, 0xcd, 0x8e, 0xa6, 0xd3, 0xfc, 0xb1,
|
||||||
0x31, 0xf9, 0x2f, 0x1f, 0x9b, 0xff, 0xea, 0xce, 0x11, 0x97, 0xff, 0x1d, 0x14, 0xfd, 0x2f, 0x54,
|
0xd3, 0x69, 0x42, 0xfe, 0x2b, 0x24, 0xe6, 0xbf, 0xba, 0x7b, 0xcc, 0x15, 0x7c, 0x07, 0x45, 0xff,
|
||||||
0xad, 0x41, 0xbb, 0x8d, 0x2d, 0x6b, 0x7f, 0xd0, 0x69, 0x71, 0xa4, 0x67, 0xde, 0x50, 0x71, 0x07,
|
0x0f, 0xd3, 0x76, 0xbf, 0xd5, 0xc2, 0xb6, 0xbd, 0xdf, 0x6f, 0x37, 0x39, 0xd2, 0x33, 0x6f, 0xa8,
|
||||||
0x76, 0x18, 0xc4, 0xff, 0x36, 0xe9, 0xf8, 0xd3, 0x96, 0xfa, 0x04, 0xb3, 0x2c, 0xf1, 0x5f, 0x8e,
|
0x7a, 0x03, 0x3b, 0x0c, 0xe2, 0x7f, 0x97, 0x72, 0xfd, 0x69, 0x4b, 0x7b, 0x82, 0x59, 0x96, 0xf8,
|
||||||
0xa9, 0xcf, 0x22, 0x0f, 0xc7, 0xe6, 0xd5, 0x4c, 0x6c, 0x5e, 0x65, 0x6d, 0xff, 0x90, 0x2a, 0x79,
|
0x1f, 0xc7, 0xd4, 0x67, 0x91, 0x87, 0x13, 0xf3, 0x6a, 0x36, 0x31, 0xaf, 0xb2, 0xb6, 0x7f, 0x44,
|
||||||
0x7d, 0xf8, 0x33, 0xf7, 0xe0, 0xf7, 0x34, 0xca, 0xf5, 0x67, 0xa2, 0x69, 0xf9, 0x53, 0xf7, 0x60,
|
0x95, 0xbc, 0x3e, 0xfc, 0xb9, 0x77, 0xf8, 0x7b, 0x1a, 0xe5, 0xfa, 0x33, 0xd1, 0xb4, 0xf2, 0xa9,
|
||||||
0x38, 0xaa, 0x7a, 0xff, 0x7c, 0xe6, 0xa6, 0x5f, 0xba, 0x9b, 0x3a, 0x95, 0xd7, 0x88, 0xc9, 0xb5,
|
0x77, 0x38, 0x1c, 0x57, 0xbd, 0x7f, 0x3e, 0x73, 0xd3, 0xaf, 0xbc, 0x4d, 0x9d, 0xca, 0x6b, 0xc4,
|
||||||
0x70, 0x13, 0x72, 0x2c, 0x0d, 0x88, 0xcd, 0xc7, 0xe4, 0x01, 0x47, 0xdd, 0x24, 0x0f, 0x88, 0x29,
|
0xf8, 0x5a, 0xb8, 0x09, 0x79, 0x96, 0x06, 0xc4, 0xe6, 0x13, 0xf2, 0x80, 0xab, 0x6e, 0x92, 0x07,
|
||||||
0xa1, 0x14, 0xe0, 0xe5, 0x7a, 0xb6, 0x29, 0x60, 0x09, 0x16, 0x23, 0x15, 0xc9, 0x5d, 0xfe, 0x93,
|
0xc4, 0x94, 0x48, 0x0a, 0xf0, 0x73, 0x3d, 0xdb, 0x14, 0xb0, 0x08, 0x0b, 0xb1, 0x8a, 0xe4, 0x2e,
|
||||||
0x04, 0x20, 0x3e, 0x7e, 0xa2, 0x7e, 0xd1, 0x84, 0xbe, 0xbe, 0x01, 0x65, 0xd6, 0x11, 0x6a, 0x8d,
|
0xff, 0x89, 0x04, 0x88, 0x8f, 0x9f, 0xa8, 0x5f, 0x34, 0xa6, 0xaf, 0xaf, 0x43, 0x85, 0x75, 0x84,
|
||||||
0xef, 0xf2, 0x33, 0x6c, 0x86, 0x53, 0x9c, 0x3a, 0x6d, 0xa1, 0x94, 0xa7, 0x2d, 0x24, 0x3f, 0x76,
|
0x9a, 0xa3, 0xbb, 0xfc, 0x14, 0x9b, 0xe1, 0x16, 0xa7, 0x6e, 0x5b, 0x28, 0xed, 0x6b, 0x0b, 0x29,
|
||||||
0x4a, 0x4f, 0x5f, 0x33, 0xe7, 0xba, 0xbf, 0x99, 0x13, 0x7e, 0xcc, 0x38, 0xdd, 0x1c, 0xb7, 0x42,
|
0x8f, 0xdd, 0xd2, 0x33, 0xd0, 0xcc, 0xb9, 0x1e, 0x6c, 0xe6, 0x44, 0x1f, 0x33, 0x4a, 0x37, 0xc7,
|
||||||
0x76, 0xba, 0x39, 0xde, 0xa0, 0x4d, 0x8c, 0x1f, 0xb4, 0xbf, 0x48, 0x38, 0x1f, 0x1b, 0x04, 0x3e,
|
0xab, 0x90, 0xdd, 0x6e, 0x8e, 0x3f, 0x68, 0xa5, 0xd1, 0x83, 0xf6, 0x97, 0x92, 0xfb, 0xc1, 0x41,
|
||||||
0x31, 0xf9, 0x3c, 0xa8, 0x5e, 0xfe, 0x79, 0xca, 0xfd, 0xc4, 0x21, 0xf0, 0x31, 0xca, 0xe7, 0x13,
|
0xe8, 0x33, 0x93, 0xcf, 0x83, 0xea, 0x95, 0x5f, 0xa4, 0xbd, 0xcf, 0x1c, 0x42, 0x1f, 0xa4, 0x7c,
|
||||||
0x70, 0xe2, 0x73, 0x49, 0x3a, 0xfe, 0x1d, 0xed, 0x32, 0x94, 0x22, 0xbe, 0x5c, 0x2b, 0x5a, 0x9e,
|
0x3e, 0x01, 0x27, 0x39, 0x97, 0x64, 0x92, 0xdf, 0xd1, 0x2e, 0x43, 0x39, 0xe6, 0xeb, 0xb5, 0x92,
|
||||||
0x03, 0xb9, 0x98, 0x34, 0x98, 0x3d, 0x6e, 0x1a, 0xcc, 0x45, 0xa4, 0xc1, 0x97, 0x21, 0xdd, 0xc3,
|
0xed, 0x3b, 0x90, 0x4b, 0x48, 0x83, 0xb9, 0xe3, 0xa6, 0xc1, 0x7c, 0x4c, 0x1a, 0x7c, 0x19, 0x32,
|
||||||
0x47, 0xe2, 0x64, 0x73, 0x88, 0x15, 0x29, 0x9b, 0xfc, 0x3e, 0x94, 0x36, 0x54, 0xbb, 0x7d, 0x78,
|
0x5d, 0x7c, 0x24, 0x4e, 0x36, 0x07, 0x58, 0x91, 0xb2, 0x29, 0xef, 0x43, 0x79, 0x5d, 0x73, 0x5a,
|
||||||
0x6c, 0x7f, 0xfb, 0x02, 0xe4, 0x4d, 0x36, 0x20, 0xa2, 0x49, 0xf2, 0x7c, 0xff, 0xe9, 0x11, 0x4d,
|
0x87, 0xc7, 0xf6, 0xb7, 0x2f, 0x41, 0xc1, 0x62, 0x03, 0x22, 0x9a, 0x64, 0xdf, 0x37, 0xa0, 0x3e,
|
||||||
0xc3, 0xc9, 0xe1, 0x95, 0xff, 0x0a, 0x50, 0x09, 0x0e, 0xa3, 0x3a, 0x4c, 0xf3, 0x63, 0x7c, 0xd6,
|
0xd1, 0x34, 0x9c, 0x5c, 0x5e, 0xe5, 0x6f, 0x00, 0xd5, 0xf0, 0x30, 0xaa, 0xc3, 0x24, 0x3f, 0xc6,
|
||||||
0x6a, 0xe4, 0x41, 0xb4, 0x14, 0xfc, 0xa2, 0xd4, 0xf7, 0x15, 0x78, 0x63, 0x4a, 0x29, 0xed, 0x79,
|
0x67, 0xad, 0x46, 0x1e, 0x44, 0x8b, 0xe1, 0xaf, 0x4a, 0x03, 0x5f, 0x82, 0x6f, 0x4e, 0xa8, 0xe5,
|
||||||
0xc8, 0xe8, 0x06, 0xf0, 0x93, 0xff, 0xd6, 0x01, 0x76, 0x3f, 0x39, 0x0f, 0x88, 0x70, 0xbb, 0xfd,
|
0x3d, 0x1f, 0x19, 0xdd, 0x00, 0x7e, 0xf2, 0xdf, 0x3c, 0xc0, 0xde, 0x67, 0xe7, 0x21, 0x11, 0x5e,
|
||||||
0x8d, 0x29, 0xa5, 0xb0, 0x27, 0x68, 0x9e, 0x25, 0x68, 0x14, 0x1b, 0x39, 0xa2, 0x86, 0x96, 0xe0,
|
0xb7, 0x7f, 0x73, 0x42, 0x2d, 0xee, 0x09, 0x9a, 0x6f, 0x09, 0x3a, 0xc5, 0x46, 0x8e, 0xa8, 0x91,
|
||||||
0x4b, 0x41, 0xee, 0x12, 0x18, 0x19, 0x7d, 0xc9, 0xf9, 0x1e, 0xa1, 0xa3, 0x5b, 0xb6, 0xd3, 0xf3,
|
0x25, 0x04, 0x52, 0x90, 0xb7, 0x04, 0x46, 0x46, 0x5f, 0x71, 0xbf, 0x47, 0x68, 0x1b, 0xb6, 0xe3,
|
||||||
0x89, 0xf8, 0x30, 0xd6, 0x95, 0xc0, 0x17, 0x4d, 0x88, 0xe8, 0x6b, 0x30, 0xcf, 0xe7, 0x5b, 0xd8,
|
0xf6, 0x7c, 0x62, 0x3e, 0x8e, 0xf5, 0x24, 0xf0, 0x45, 0x13, 0x22, 0xfa, 0x06, 0xcc, 0xf1, 0xf9,
|
||||||
0x6e, 0xa9, 0xee, 0x77, 0x09, 0xbc, 0xfd, 0x73, 0x2d, 0x28, 0x2a, 0xf2, 0x53, 0x8a, 0xc6, 0x94,
|
0x36, 0x76, 0x9a, 0x9a, 0xf7, 0x5d, 0x02, 0x6f, 0xff, 0x5c, 0x0b, 0x8b, 0x8a, 0xfd, 0x94, 0x62,
|
||||||
0x32, 0xb7, 0x17, 0x31, 0x8c, 0xd6, 0xa1, 0xc4, 0xbb, 0xe5, 0x7b, 0xa4, 0x48, 0xe0, 0x6d, 0xa0,
|
0x73, 0x42, 0x9d, 0xdd, 0x8b, 0x19, 0x46, 0x6b, 0x50, 0xe6, 0xdd, 0xf2, 0x3d, 0x52, 0x24, 0xf0,
|
||||||
0x0b, 0xc1, 0xd6, 0xb1, 0xf7, 0x75, 0xbd, 0x31, 0xa5, 0x14, 0x0d, 0x97, 0x4a, 0xf4, 0xc4, 0x45,
|
0x36, 0xd0, 0x85, 0x70, 0xeb, 0xd8, 0xff, 0xba, 0xbe, 0x39, 0xa1, 0x96, 0x4c, 0x8f, 0x4a, 0xf4,
|
||||||
0xb4, 0x69, 0x31, 0xcb, 0x0b, 0xe9, 0xa5, 0xa0, 0x0c, 0xdf, 0xcb, 0x24, 0xd1, 0x93, 0xe1, 0x21,
|
0xc4, 0x45, 0xb4, 0x68, 0x31, 0xcb, 0x0b, 0xe9, 0xc5, 0xb0, 0x8c, 0xc0, 0xcb, 0x24, 0xd1, 0x93,
|
||||||
0x13, 0x53, 0x71, 0x29, 0xc4, 0x54, 0xf9, 0xa0, 0xa9, 0x82, 0x07, 0x33, 0xc4, 0x54, 0x86, 0xa0,
|
0xe9, 0x23, 0x13, 0x53, 0x71, 0x29, 0xc4, 0x54, 0x85, 0xb0, 0xa9, 0xc2, 0x07, 0x33, 0xc4, 0x54,
|
||||||
0x11, 0x25, 0xf3, 0xc9, 0x54, 0xc9, 0x85, 0xa0, 0x92, 0x43, 0x07, 0x1f, 0x44, 0xc9, 0x86, 0x43,
|
0xa6, 0xa0, 0x11, 0x25, 0xf3, 0xc9, 0x54, 0xc9, 0xc5, 0xb0, 0x92, 0x23, 0x07, 0x1f, 0x44, 0xc9,
|
||||||
0x44, 0xf7, 0x61, 0xd6, 0xab, 0x05, 0x61, 0x70, 0xa0, 0x72, 0xe4, 0x48, 0x65, 0x04, 0xad, 0x5e,
|
0xa6, 0x4b, 0x44, 0xf7, 0x61, 0xc6, 0xaf, 0x05, 0x61, 0x70, 0xa0, 0x72, 0x94, 0x58, 0x65, 0x84,
|
||||||
0x35, 0x82, 0x63, 0xe8, 0x21, 0xcc, 0x71, 0xa9, 0xfb, 0x34, 0xc5, 0x0a, 0xb1, 0x45, 0x2a, 0xf6,
|
0xad, 0x3e, 0x6d, 0x86, 0xc7, 0xd0, 0x43, 0x98, 0xe5, 0x52, 0xf7, 0x69, 0x8a, 0x15, 0x62, 0x4b,
|
||||||
0x4a, 0x50, 0x6c, 0x44, 0x41, 0xd3, 0x98, 0x52, 0x90, 0x11, 0x1a, 0x24, 0x1a, 0x17, 0x00, 0xc3,
|
0x54, 0xec, 0x95, 0xb0, 0xd8, 0x98, 0x82, 0x66, 0x73, 0x42, 0x45, 0x66, 0x64, 0x90, 0x68, 0x5c,
|
||||||
0xac, 0x56, 0x0a, 0x6a, 0x3c, 0xa2, 0xcb, 0x42, 0x34, 0x6e, 0x79, 0xc8, 0xe8, 0x36, 0xcc, 0x08,
|
0x00, 0x0c, 0xb3, 0x5a, 0x39, 0xac, 0xf1, 0x98, 0x2e, 0x0b, 0xd1, 0xb8, 0xed, 0x23, 0xa3, 0xdb,
|
||||||
0x29, 0xdc, 0x70, 0xec, 0x0c, 0xff, 0x62, 0x48, 0x4c, 0xd0, 0x72, 0xe2, 0xe9, 0xdc, 0x74, 0xf7,
|
0x30, 0x25, 0xa4, 0x70, 0xc3, 0xb1, 0x33, 0xfc, 0x8b, 0x11, 0x31, 0x61, 0xcb, 0x89, 0xa7, 0x73,
|
||||||
0x61, 0x56, 0x08, 0xea, 0xaa, 0x4f, 0x30, 0x87, 0x49, 0x7a, 0x8a, 0x1f, 0x55, 0x1e, 0x85, 0xde,
|
0xd3, 0xdd, 0x87, 0x19, 0x21, 0xa8, 0xa3, 0x3d, 0xc1, 0x1c, 0x26, 0xe9, 0x29, 0x7e, 0x5c, 0x79,
|
||||||
0x55, 0x88, 0xf6, 0xac, 0xe0, 0x18, 0xd1, 0x9e, 0x6f, 0x93, 0x42, 0x7b, 0xe5, 0xa0, 0xf6, 0x62,
|
0x14, 0x79, 0x57, 0x21, 0xda, 0xb3, 0xc3, 0x63, 0x44, 0x7b, 0x81, 0x4d, 0x0a, 0xed, 0x55, 0xc2,
|
||||||
0x2b, 0x73, 0xa2, 0x3d, 0x2b, 0x34, 0x88, 0x1e, 0xc3, 0x39, 0x21, 0xd8, 0x6f, 0x97, 0x0a, 0x95,
|
0xda, 0x4b, 0xac, 0xcc, 0x89, 0xf6, 0xec, 0xc8, 0x20, 0x7a, 0x0c, 0xe7, 0x84, 0xe0, 0xa0, 0x5d,
|
||||||
0x7c, 0x35, 0x24, 0x39, 0xda, 0x30, 0x62, 0xcf, 0x3e, 0xcb, 0xac, 0xbb, 0xd0, 0x4f, 0x3d, 0xb1,
|
0xaa, 0x54, 0xf2, 0xd5, 0x88, 0xe4, 0x78, 0xc3, 0x88, 0x3d, 0x07, 0x2c, 0xb3, 0xe6, 0x41, 0x3f,
|
||||||
0x1a, 0x0c, 0xa7, 0x70, 0x4d, 0x45, 0xc2, 0xc9, 0x72, 0xa9, 0x68, 0x0b, 0x2a, 0x42, 0x84, 0xc6,
|
0xf5, 0xc4, 0xe9, 0x70, 0x38, 0x45, 0x6b, 0x2a, 0x12, 0x4e, 0xb6, 0x47, 0x45, 0x5b, 0x50, 0x15,
|
||||||
0x73, 0x68, 0x0d, 0x05, 0x0f, 0xb0, 0xa2, 0x6b, 0x84, 0xc6, 0x94, 0x52, 0xb6, 0xfc, 0x23, 0x1b,
|
0x22, 0x74, 0x9e, 0x43, 0x6b, 0x28, 0x7c, 0x80, 0x15, 0x5f, 0x23, 0x6c, 0x4e, 0xa8, 0x15, 0x3b,
|
||||||
0x05, 0xc8, 0xf1, 0x51, 0xf9, 0x2d, 0x98, 0xe6, 0x38, 0xcb, 0x53, 0xf2, 0x17, 0xa1, 0x60, 0xf2,
|
0x38, 0xb2, 0x5e, 0x84, 0x3c, 0x1f, 0x55, 0xde, 0x82, 0x49, 0x8e, 0xb3, 0x3c, 0x25, 0x7f, 0x19,
|
||||||
0x6b, 0x01, 0xd9, 0x8b, 0x21, 0xc8, 0x66, 0xe3, 0x14, 0xb3, 0x5d, 0x6e, 0xf9, 0x9f, 0x00, 0xd5,
|
0x8a, 0x16, 0xbf, 0x16, 0x90, 0xbd, 0x10, 0x81, 0x6c, 0x36, 0x4e, 0x31, 0xdb, 0xe3, 0x56, 0xfe,
|
||||||
0x10, 0x03, 0xda, 0x8c, 0x46, 0xed, 0x8b, 0x71, 0xa8, 0xcd, 0xa6, 0x86, 0x60, 0xfb, 0x66, 0x04,
|
0x05, 0x30, 0x1d, 0x61, 0x40, 0x1b, 0xf1, 0xa8, 0x7d, 0x31, 0x09, 0xb5, 0xd9, 0xd4, 0x08, 0x6c,
|
||||||
0x6c, 0x2f, 0x46, 0xc2, 0xb6, 0x23, 0xc0, 0x83, 0xdb, 0x9b, 0xd1, 0xb8, 0x7d, 0x31, 0x0e, 0xb7,
|
0xdf, 0x8c, 0x81, 0xed, 0x85, 0x58, 0xd8, 0x76, 0x05, 0xf8, 0x70, 0x7b, 0x23, 0x1e, 0xb7, 0x2f,
|
||||||
0x83, 0x8b, 0xe0, 0xa6, 0x7c, 0x23, 0x0a, 0xb8, 0x2f, 0x44, 0x03, 0xb7, 0x23, 0xc2, 0x8b, 0xdc,
|
0x26, 0xe1, 0x76, 0x78, 0x11, 0xdc, 0x94, 0x6f, 0xc4, 0x01, 0xf7, 0x85, 0x78, 0xe0, 0x76, 0x45,
|
||||||
0x5f, 0x1f, 0x81, 0xdc, 0x2f, 0x8c, 0x42, 0x6e, 0x47, 0x6a, 0x34, 0x74, 0x6f, 0x44, 0x42, 0xf7,
|
0xf8, 0x91, 0xfb, 0x9b, 0x43, 0x90, 0xfb, 0x85, 0x61, 0xc8, 0xed, 0x4a, 0x8d, 0x87, 0xee, 0xf5,
|
||||||
0x52, 0x0c, 0x74, 0x3b, 0xc2, 0x7c, 0xd8, 0xbd, 0x19, 0x8d, 0xdd, 0x17, 0xe3, 0xb0, 0xdb, 0xd5,
|
0x58, 0xe8, 0x5e, 0x4c, 0x80, 0x6e, 0x57, 0x58, 0x00, 0xbb, 0x37, 0xe2, 0xb1, 0xfb, 0x62, 0x12,
|
||||||
0x95, 0x0f, 0xbc, 0x6f, 0x46, 0x80, 0xf7, 0x62, 0x24, 0x78, 0xbb, 0x06, 0x73, 0xd1, 0xfb, 0x8d,
|
0x76, 0x7b, 0xba, 0x0a, 0x80, 0xf7, 0xcd, 0x18, 0xf0, 0x5e, 0x88, 0x05, 0x6f, 0xcf, 0x60, 0x1e,
|
||||||
0x28, 0xf4, 0xbe, 0x10, 0x8d, 0xde, 0xae, 0xa6, 0x3d, 0xf0, 0xfd, 0x60, 0x18, 0x7c, 0x5f, 0x19,
|
0x7a, 0xbf, 0x11, 0x87, 0xde, 0x17, 0xe2, 0xd1, 0xdb, 0xd3, 0xb4, 0x0f, 0xbe, 0x1f, 0x0c, 0x82,
|
||||||
0x0a, 0xdf, 0x8e, 0xbc, 0x08, 0xfc, 0x7e, 0x34, 0x14, 0xbf, 0xaf, 0x0e, 0xc7, 0x6f, 0x47, 0x70,
|
0xef, 0x2b, 0x03, 0xe1, 0xdb, 0x95, 0x17, 0x83, 0xdf, 0x8f, 0x06, 0xe2, 0xf7, 0xd5, 0xc1, 0xf8,
|
||||||
0x14, 0x80, 0x6f, 0x46, 0x03, 0xf8, 0xc5, 0x38, 0x00, 0x77, 0xd5, 0xee, 0x43, 0xf0, 0x46, 0x0c,
|
0xed, 0x0a, 0x8e, 0x03, 0xf0, 0x8d, 0x78, 0x00, 0xbf, 0x98, 0x04, 0xe0, 0x9e, 0xda, 0x03, 0x08,
|
||||||
0x82, 0x2f, 0xc7, 0x22, 0xb8, 0x23, 0x28, 0x00, 0xe1, 0x0f, 0x86, 0x41, 0xf8, 0x95, 0xa1, 0x10,
|
0xbe, 0x99, 0x80, 0xe0, 0x4b, 0x89, 0x08, 0xee, 0x0a, 0x0a, 0x41, 0xf8, 0x83, 0x41, 0x10, 0x7e,
|
||||||
0xee, 0x6a, 0x30, 0x8c, 0xe1, 0x8f, 0x86, 0x62, 0xf8, 0xd5, 0xe1, 0x18, 0xee, 0x6a, 0x30, 0x02,
|
0x65, 0x20, 0x84, 0x7b, 0x1a, 0x8c, 0x62, 0xf8, 0xa3, 0x81, 0x18, 0x7e, 0x75, 0x30, 0x86, 0x7b,
|
||||||
0xc4, 0xbf, 0x3a, 0x1c, 0xc4, 0xaf, 0x8d, 0x00, 0x71, 0x47, 0x76, 0x24, 0x8a, 0x6f, 0x44, 0xa2,
|
0x1a, 0x8c, 0x01, 0xf1, 0xaf, 0x0f, 0x06, 0xf1, 0x6b, 0x43, 0x40, 0xdc, 0x95, 0x1d, 0x8b, 0xe2,
|
||||||
0xf8, 0x52, 0x0c, 0x8a, 0xbb, 0x91, 0xe5, 0x85, 0xf1, 0xed, 0x58, 0x18, 0xbf, 0x3c, 0x04, 0xc6,
|
0xeb, 0xb1, 0x28, 0xbe, 0x98, 0x80, 0xe2, 0x5e, 0x64, 0xf9, 0x61, 0x7c, 0x3b, 0x11, 0xc6, 0x2f,
|
||||||
0x1d, 0x59, 0x21, 0x1c, 0x07, 0xc8, 0x8b, 0xe1, 0xb5, 0x7f, 0x54, 0x21, 0xbf, 0xc5, 0x65, 0xa0,
|
0x0f, 0x80, 0x71, 0x57, 0x56, 0x04, 0xc7, 0x01, 0x0a, 0x62, 0x78, 0xf5, 0x9f, 0xd3, 0x50, 0xd8,
|
||||||
0x2d, 0x28, 0x31, 0xd8, 0xe4, 0xff, 0xcb, 0x0e, 0x2f, 0x91, 0xa5, 0x11, 0x58, 0x8c, 0xea, 0x50,
|
0xe2, 0x32, 0xd0, 0x16, 0x94, 0x19, 0x6c, 0xf2, 0x7f, 0x66, 0x07, 0x97, 0xc8, 0xf2, 0x10, 0x2c,
|
||||||
0xb8, 0x8d, 0x6d, 0x2e, 0x6b, 0x48, 0xad, 0x2c, 0x0d, 0x03, 0x64, 0xb2, 0x28, 0xa6, 0xcb, 0xb8,
|
0x46, 0x75, 0x28, 0xde, 0xc6, 0x0e, 0x97, 0x35, 0xa0, 0x56, 0x96, 0x07, 0x01, 0x32, 0x59, 0x14,
|
||||||
0x45, 0xf9, 0xb2, 0xa9, 0x34, 0x02, 0x9b, 0x51, 0x03, 0x8a, 0x44, 0xa9, 0x6c, 0xcc, 0x42, 0xc3,
|
0xd3, 0x65, 0xd2, 0xa2, 0x02, 0xd9, 0x54, 0x1e, 0x82, 0xcd, 0x68, 0x13, 0x4a, 0x44, 0xa9, 0x6c,
|
||||||
0xca, 0x67, 0x69, 0x28, 0x44, 0x23, 0x0c, 0x73, 0xbb, 0x62, 0x7b, 0x5e, 0x30, 0x1d, 0xaf, 0x8c,
|
0xcc, 0x46, 0x83, 0xca, 0x67, 0x79, 0x20, 0x44, 0x23, 0x0c, 0xb3, 0xbb, 0x62, 0x7b, 0x7e, 0x30,
|
||||||
0x96, 0xc6, 0xc4, 0x6c, 0xf4, 0x16, 0x14, 0xa9, 0xb7, 0xf2, 0x6f, 0x75, 0x87, 0xd6, 0xd3, 0xd2,
|
0x1d, 0xad, 0x8c, 0x96, 0x47, 0xc4, 0x6c, 0xf4, 0x16, 0x94, 0xa8, 0xb7, 0xf2, 0x6f, 0x75, 0x07,
|
||||||
0x70, 0xc8, 0xa6, 0x06, 0xa6, 0x51, 0xca, 0x85, 0x0d, 0x2f, 0xac, 0xa5, 0x11, 0xd8, 0xcd, 0x0d,
|
0xd6, 0xd3, 0xf2, 0x60, 0xc8, 0xa6, 0x06, 0xa6, 0x51, 0xca, 0x85, 0x0d, 0x2e, 0xac, 0xe5, 0x21,
|
||||||
0xcc, 0x65, 0x0d, 0xa9, 0xb0, 0xa5, 0x61, 0x00, 0x2e, 0x2c, 0xc2, 0x06, 0x7c, 0x16, 0x09, 0xd5,
|
0xd8, 0xcd, 0x0d, 0xcc, 0x65, 0x0d, 0xa8, 0xb0, 0xe5, 0x41, 0x00, 0x2e, 0x2c, 0xc2, 0x06, 0x02,
|
||||||
0xda, 0xd2, 0x50, 0x28, 0x47, 0xef, 0x42, 0xd5, 0x13, 0xd8, 0x7c, 0x5d, 0x63, 0xd4, 0xdc, 0xd2,
|
0x16, 0x89, 0xd4, 0xda, 0xf2, 0x40, 0x28, 0x47, 0xef, 0xc2, 0xb4, 0x2f, 0xb0, 0xf9, 0xba, 0x46,
|
||||||
0x38, 0xc0, 0x8e, 0x5a, 0x80, 0xbc, 0xa1, 0xcd, 0xc5, 0x8f, 0x53, 0x7b, 0x4b, 0x63, 0x01, 0x3c,
|
0xa8, 0xb9, 0xe5, 0x51, 0x80, 0x1d, 0x35, 0x01, 0xf9, 0x43, 0x9b, 0x8b, 0x1f, 0xa5, 0xf6, 0x96,
|
||||||
0xb1, 0x0e, 0x7d, 0xae, 0x38, 0xce, 0x1e, 0x5e, 0x84, 0x4b, 0x23, 0x20, 0x1e, 0xed, 0xc0, 0x34,
|
0x47, 0x02, 0x78, 0x62, 0x1d, 0xfa, 0x5c, 0x71, 0x9c, 0x3d, 0xb8, 0x08, 0x97, 0x87, 0x40, 0x3c,
|
||||||
0xb3, 0x97, 0x90, 0x37, 0xa2, 0x1a, 0x97, 0x46, 0x61, 0x3d, 0xd1, 0xaf, 0x8b, 0xc8, 0x42, 0xea,
|
0xda, 0x81, 0x49, 0x66, 0x2f, 0x21, 0x6f, 0x48, 0x35, 0x2e, 0x0f, 0xc3, 0x7a, 0xa2, 0x5f, 0x0f,
|
||||||
0x18, 0x55, 0xb9, 0x34, 0x0e, 0xec, 0x13, 0xfd, 0x7a, 0xd4, 0x2e, 0xc4, 0x8f, 0x53, 0x9d, 0x4b,
|
0x91, 0x85, 0xd4, 0x11, 0xaa, 0x72, 0x79, 0x14, 0xd8, 0x27, 0xfa, 0xf5, 0xa9, 0x5d, 0x88, 0x1f,
|
||||||
0x63, 0xc1, 0x3f, 0xda, 0x83, 0x59, 0xaf, 0xde, 0xc5, 0x13, 0xc6, 0xaa, 0xd2, 0xa5, 0xf1, 0xd2,
|
0xa5, 0x3a, 0x97, 0x47, 0x82, 0x7f, 0xb4, 0x07, 0x33, 0x7e, 0xbd, 0x8b, 0x27, 0x8c, 0x54, 0xa5,
|
||||||
0x00, 0xba, 0x03, 0x25, 0xef, 0x3f, 0x12, 0x68, 0x68, 0xbd, 0x2e, 0x0d, 0xcf, 0x03, 0xe8, 0x1d,
|
0xcb, 0xa3, 0xa5, 0x01, 0x74, 0x07, 0xca, 0xfe, 0x7f, 0x24, 0xd0, 0xc0, 0x7a, 0x5d, 0x1e, 0x9c,
|
||||||
0x28, 0x0b, 0xd0, 0x16, 0x8b, 0x1d, 0x59, 0xb8, 0x4b, 0xa3, 0x73, 0x02, 0x7a, 0x0d, 0x32, 0xb4,
|
0x07, 0xd0, 0x3b, 0x50, 0x11, 0xa0, 0x2d, 0x16, 0x3b, 0xb4, 0x70, 0x97, 0x87, 0xe7, 0x04, 0xf4,
|
||||||
0xe0, 0x46, 0xf3, 0xd1, 0x5d, 0x15, 0x69, 0x21, 0xa6, 0x74, 0x47, 0x0f, 0xa1, 0xc2, 0x40, 0x9e,
|
0x1a, 0x64, 0x69, 0xc1, 0x8d, 0xe6, 0xe2, 0xbb, 0x2a, 0xf2, 0x7c, 0x42, 0xe9, 0x8e, 0x1e, 0x42,
|
||||||
0x8b, 0xbe, 0xd7, 0xd1, 0x22, 0x96, 0x14, 0xf8, 0x83, 0x34, 0x62, 0x49, 0xa1, 0x3f, 0x22, 0xbf,
|
0x95, 0x81, 0x3c, 0x17, 0x7d, 0xaf, 0xad, 0xc7, 0x2c, 0x29, 0xf4, 0x17, 0x69, 0xcc, 0x92, 0x22,
|
||||||
0x02, 0x15, 0x9f, 0xb3, 0x12, 0xda, 0xe5, 0xe1, 0xfe, 0x4a, 0x24, 0xcb, 0x23, 0x5c, 0x96, 0x88,
|
0x7f, 0x45, 0x7e, 0x0d, 0xaa, 0x01, 0x67, 0x25, 0xb4, 0xcb, 0x83, 0xfd, 0x95, 0x48, 0x56, 0x86,
|
||||||
0xd9, 0x85, 0x19, 0xcf, 0x4f, 0x57, 0x84, 0x12, 0x76, 0x74, 0xff, 0xef, 0x61, 0xd2, 0xa5, 0x18,
|
0xb8, 0x2c, 0x11, 0xb3, 0x0b, 0x53, 0xbe, 0x1f, 0xaf, 0x08, 0x25, 0xea, 0xe8, 0xc1, 0x5f, 0xc4,
|
||||||
0x06, 0x57, 0x68, 0x0b, 0x50, 0xc0, 0x34, 0x84, 0x7a, 0x65, 0x94, 0x75, 0x88, 0xf0, 0xab, 0x23,
|
0xe4, 0x4b, 0x09, 0x0c, 0x9e, 0xd0, 0x26, 0xa0, 0x90, 0x69, 0x08, 0xf5, 0xca, 0x30, 0xeb, 0x10,
|
||||||
0x0d, 0xc4, 0x15, 0xe2, 0x73, 0xd3, 0x68, 0x85, 0x04, 0xff, 0xfe, 0x8a, 0x50, 0x48, 0xf8, 0x6f,
|
0xe1, 0x57, 0x87, 0x1a, 0x88, 0x2b, 0x24, 0xe0, 0xa6, 0xf1, 0x0a, 0x09, 0xff, 0x01, 0x16, 0xa3,
|
||||||
0xac, 0x77, 0xa0, 0xec, 0xf5, 0xd1, 0x80, 0x0d, 0xa3, 0xff, 0x91, 0xf2, 0xda, 0x30, 0xee, 0xb7,
|
0x90, 0xe8, 0x1f, 0x59, 0xef, 0x40, 0xc5, 0xef, 0xa3, 0x21, 0x1b, 0xc6, 0xff, 0x27, 0xe5, 0xb7,
|
||||||
0xa1, 0x77, 0xa1, 0xea, 0xcf, 0x61, 0x84, 0xe8, 0x5b, 0x50, 0xf4, 0x9f, 0x39, 0x7e, 0x78, 0x88,
|
0x61, 0xd2, 0x6f, 0x43, 0xef, 0xc2, 0x74, 0x30, 0x87, 0x11, 0x62, 0x60, 0x41, 0xf1, 0x7f, 0xe6,
|
||||||
0xf9, 0x61, 0x86, 0xe4, 0x41, 0xcf, 0x9f, 0x2e, 0xde, 0xc0, 0x0a, 0xff, 0x47, 0xe3, 0x0d, 0xac,
|
0x04, 0xe1, 0x21, 0xe1, 0x87, 0x19, 0x92, 0x07, 0x7d, 0x7f, 0xba, 0xf8, 0x03, 0x2b, 0xfa, 0x1f,
|
||||||
0x88, 0xdf, 0x63, 0x36, 0xd2, 0x8f, 0x93, 0xfd, 0xbd, 0xbd, 0x2c, 0x3d, 0x97, 0x7d, 0xf5, 0x3f,
|
0x8d, 0x3f, 0xb0, 0x62, 0x7e, 0x8f, 0x59, 0xcf, 0x3c, 0x4e, 0xf5, 0xf6, 0xf6, 0x72, 0xf4, 0x5c,
|
||||||
0x01, 0x00, 0x00, 0xff, 0xff, 0x48, 0x9e, 0xe0, 0x05, 0xd0, 0x44, 0x00, 0x00,
|
0xf6, 0xd5, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x70, 0x7c, 0x53, 0x8c, 0xd4, 0x44, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
||||||
type DRPCMetainfoClient interface {
|
type DRPCMetainfoClient interface {
|
||||||
|
@ -215,7 +215,7 @@ message ListSegmentsRequestOld {
|
|||||||
bytes bucket = 1;
|
bytes bucket = 1;
|
||||||
bytes prefix = 2;
|
bytes prefix = 2;
|
||||||
bytes start_after = 3;
|
bytes start_after = 3;
|
||||||
bytes end_before = 4;
|
bytes end_before = 4 [deprecated=true];
|
||||||
bool recursive = 5;
|
bool recursive = 5;
|
||||||
int32 limit = 6;
|
int32 limit = 6;
|
||||||
fixed32 meta_flags = 7;
|
fixed32 meta_flags = 7;
|
||||||
|
@ -77,9 +77,9 @@ func (create CreateObject) Object(bucket Bucket, path Path) Object {
|
|||||||
type ListDirection int8
|
type ListDirection int8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Before lists backwards from cursor, without cursor
|
// Before lists backwards from cursor, without cursor [NOT SUPPORTED]
|
||||||
Before = ListDirection(-2)
|
Before = ListDirection(-2)
|
||||||
// Backward lists backwards from cursor, including cursor
|
// Backward lists backwards from cursor, including cursor [NOT SUPPORTED]
|
||||||
Backward = ListDirection(-1)
|
Backward = ListDirection(-1)
|
||||||
// Forward lists forwards from cursor, including cursor
|
// Forward lists forwards from cursor, including cursor
|
||||||
Forward = ListDirection(1)
|
Forward = ListDirection(1)
|
||||||
@ -114,24 +114,12 @@ func (opts ListOptions) NextPage(list ObjectList) ListOptions {
|
|||||||
return ListOptions{}
|
return ListOptions{}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch opts.Direction {
|
|
||||||
case Before, Backward:
|
|
||||||
return ListOptions{
|
|
||||||
Prefix: opts.Prefix,
|
|
||||||
Cursor: list.Items[0].Path,
|
|
||||||
Direction: Before,
|
|
||||||
Limit: opts.Limit,
|
|
||||||
}
|
|
||||||
case After, Forward:
|
|
||||||
return ListOptions{
|
return ListOptions{
|
||||||
Prefix: opts.Prefix,
|
Prefix: opts.Prefix,
|
||||||
Cursor: list.Items[len(list.Items)-1].Path,
|
Cursor: list.Items[len(list.Items)-1].Path,
|
||||||
Direction: After,
|
Direction: After,
|
||||||
Limit: opts.Limit,
|
Limit: opts.Limit,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return ListOptions{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BucketListOptions lists objects
|
// BucketListOptions lists objects
|
||||||
@ -153,22 +141,11 @@ func (opts BucketListOptions) NextPage(list BucketList) BucketListOptions {
|
|||||||
return BucketListOptions{}
|
return BucketListOptions{}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch opts.Direction {
|
|
||||||
case Before, Backward:
|
|
||||||
return BucketListOptions{
|
|
||||||
Cursor: list.Items[0].Name,
|
|
||||||
Direction: Before,
|
|
||||||
Limit: opts.Limit,
|
|
||||||
}
|
|
||||||
case After, Forward:
|
|
||||||
return BucketListOptions{
|
return BucketListOptions{
|
||||||
Cursor: list.Items[len(list.Items)-1].Name,
|
Cursor: list.Items[len(list.Items)-1].Name,
|
||||||
Direction: After,
|
Direction: After,
|
||||||
Limit: opts.Limit,
|
Limit: opts.Limit,
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return BucketListOptions{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MetainfoLimits lists limits specified for the Metainfo database
|
// MetainfoLimits lists limits specified for the Metainfo database
|
||||||
|
@ -2431,7 +2431,13 @@
|
|||||||
{
|
{
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"name": "end_before",
|
"name": "end_before",
|
||||||
"type": "bytes"
|
"type": "bytes",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"name": "deprecated",
|
||||||
|
"value": "true"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 5,
|
"id": 5,
|
||||||
|
@ -438,7 +438,7 @@ func (endpoint *Endpoint) ListSegmentsOld(ctx context.Context, req *pb.ListSegme
|
|||||||
return nil, rpcstatus.Error(rpcstatus.InvalidArgument, err.Error())
|
return nil, rpcstatus.Error(rpcstatus.InvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
items, more, err := endpoint.metainfo.List(ctx, prefix, string(req.StartAfter), string(req.EndBefore), req.Recursive, req.Limit, req.MetaFlags)
|
items, more, err := endpoint.metainfo.List(ctx, prefix, string(req.StartAfter), req.Recursive, req.Limit, req.MetaFlags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rpcstatus.Error(rpcstatus.Internal, err.Error())
|
return nil, rpcstatus.Error(rpcstatus.Internal, err.Error())
|
||||||
}
|
}
|
||||||
@ -924,7 +924,7 @@ func (endpoint *Endpoint) setBucketAttribution(ctx context.Context, header *pb.R
|
|||||||
return rpcstatus.Error(rpcstatus.InvalidArgument, err.Error())
|
return rpcstatus.Error(rpcstatus.InvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
items, _, err := endpoint.metainfo.List(ctx, prefix, "", "", true, 1, 0)
|
items, _, err := endpoint.metainfo.List(ctx, prefix, "", true, 1, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
endpoint.log.Error("error while listing segments", zap.Error(err))
|
endpoint.log.Error("error while listing segments", zap.Error(err))
|
||||||
return rpcstatus.Error(rpcstatus.Internal, err.Error())
|
return rpcstatus.Error(rpcstatus.Internal, err.Error())
|
||||||
@ -1292,8 +1292,7 @@ func (endpoint *Endpoint) ListObjects(ctx context.Context, req *pb.ObjectListReq
|
|||||||
|
|
||||||
metaflags := meta.All
|
metaflags := meta.All
|
||||||
// TODO use flags
|
// TODO use flags
|
||||||
// TODO find out how EncryptedCursor -> startAfter/endAfter
|
segments, more, err := endpoint.metainfo.List(ctx, prefix, string(req.EncryptedCursor), req.Recursive, req.Limit, metaflags)
|
||||||
segments, more, err := endpoint.metainfo.List(ctx, prefix, string(req.EncryptedCursor), "", req.Recursive, req.Limit, metaflags)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rpcstatus.Error(rpcstatus.Internal, err.Error())
|
return nil, rpcstatus.Error(rpcstatus.Internal, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ func (s *Service) GetWithBytes(ctx context.Context, path string) (pointerBytes [
|
|||||||
}
|
}
|
||||||
|
|
||||||
// List returns all Path keys in the pointers bucket
|
// List returns all Path keys in the pointers bucket
|
||||||
func (s *Service) List(ctx context.Context, prefix string, startAfter string, endBefore string, recursive bool, limit int32,
|
func (s *Service) List(ctx context.Context, prefix string, startAfter string, recursive bool, limit int32,
|
||||||
metaFlags uint32) (items []*pb.ListResponse_Item, more bool, err error) {
|
metaFlags uint32) (items []*pb.ListResponse_Item, more bool, err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
@ -211,7 +211,6 @@ func (s *Service) List(ctx context.Context, prefix string, startAfter string, en
|
|||||||
rawItems, more, err := storage.ListV2(ctx, s.db, storage.ListOptions{
|
rawItems, more, err := storage.ListV2(ctx, s.db, storage.ListOptions{
|
||||||
Prefix: prefixKey,
|
Prefix: prefixKey,
|
||||||
StartAfter: storage.Key(startAfter),
|
StartAfter: storage.Key(startAfter),
|
||||||
EndBefore: storage.Key(endBefore),
|
|
||||||
Recursive: recursive,
|
Recursive: recursive,
|
||||||
Limit: int(limit),
|
Limit: int(limit),
|
||||||
IncludeValue: metaFlags != meta.None,
|
IncludeValue: metaFlags != meta.None,
|
||||||
|
@ -597,7 +597,7 @@ func TestRepairMultipleDisqualified(t *testing.T) {
|
|||||||
|
|
||||||
// get a remote segment from metainfo
|
// get a remote segment from metainfo
|
||||||
metainfo := satellite.Metainfo.Service
|
metainfo := satellite.Metainfo.Service
|
||||||
listResponse, _, err := metainfo.List(ctx, "", "", "", true, 0, 0)
|
listResponse, _, err := metainfo.List(ctx, "", "", true, 0, 0)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
var path string
|
var path string
|
||||||
@ -1036,7 +1036,7 @@ func getRemoteSegment(
|
|||||||
|
|
||||||
// get a remote segment from metainfo
|
// get a remote segment from metainfo
|
||||||
metainfo := satellite.Metainfo.Service
|
metainfo := satellite.Metainfo.Service
|
||||||
listResponse, _, err := metainfo.List(ctx, "", "", "", true, 0, 0)
|
listResponse, _, err := metainfo.List(ctx, "", "", true, 0, 0)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
for _, v := range listResponse {
|
for _, v := range listResponse {
|
||||||
|
@ -226,12 +226,7 @@ func (client *Client) GetAll(ctx context.Context, keys storage.Keys) (_ storage.
|
|||||||
func (client *Client) Iterate(ctx context.Context, opts storage.IterateOptions, fn func(context.Context, storage.Iterator) error) (err error) {
|
func (client *Client) Iterate(ctx context.Context, opts storage.IterateOptions, fn func(context.Context, storage.Iterator) error) (err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
return client.view(func(bucket *bolt.Bucket) error {
|
return client.view(func(bucket *bolt.Bucket) error {
|
||||||
var cursor advancer
|
var cursor advancer = forward{bucket.Cursor()}
|
||||||
if !opts.Reverse {
|
|
||||||
cursor = forward{bucket.Cursor()}
|
|
||||||
} else {
|
|
||||||
cursor = backward{bucket.Cursor()}
|
|
||||||
}
|
|
||||||
|
|
||||||
start := true
|
start := true
|
||||||
lastPrefix := []byte{}
|
lastPrefix := []byte{}
|
||||||
@ -307,46 +302,6 @@ func (cursor forward) Advance() (key, value []byte) {
|
|||||||
return cursor.Next()
|
return cursor.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
type backward struct {
|
|
||||||
*bolt.Cursor
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cursor backward) PositionToFirst(prefix, first storage.Key) (key, value []byte) {
|
|
||||||
if prefix.IsZero() {
|
|
||||||
// there's no prefix
|
|
||||||
if first.IsZero() {
|
|
||||||
// and no first item, so start from the end
|
|
||||||
return cursor.Last()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// there's a prefix
|
|
||||||
if first.IsZero() || storage.AfterPrefix(prefix).Less(first) {
|
|
||||||
// there's no first, or it's after our prefix
|
|
||||||
// storage.AfterPrefix("axxx/") is the next item after prefixes
|
|
||||||
// so we position to the item before
|
|
||||||
nextkey := storage.AfterPrefix(prefix)
|
|
||||||
_, _ = cursor.Seek(nextkey)
|
|
||||||
return cursor.Prev()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise try to position on first or one before that
|
|
||||||
key, value = cursor.Seek(first)
|
|
||||||
if !bytes.Equal(key, first) {
|
|
||||||
key, value = cursor.Prev()
|
|
||||||
}
|
|
||||||
return key, value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cursor backward) SkipPrefix(prefix storage.Key) (key, value []byte) {
|
|
||||||
_, _ = cursor.Seek(prefix)
|
|
||||||
return cursor.Prev()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cursor backward) Advance() (key, value []byte) {
|
|
||||||
return cursor.Prev()
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompareAndSwap atomically compares and swaps oldValue with newValue
|
// CompareAndSwap atomically compares and swaps oldValue with newValue
|
||||||
func (client *Client) CompareAndSwap(ctx context.Context, key storage.Key, oldValue, newValue storage.Value) (err error) {
|
func (client *Client) CompareAndSwap(ctx context.Context, key storage.Key, oldValue, newValue storage.Value) (err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
@ -85,8 +85,6 @@ type IterateOptions struct {
|
|||||||
First Key
|
First Key
|
||||||
// Recurse, do not collapse items based on Delimiter
|
// Recurse, do not collapse items based on Delimiter
|
||||||
Recurse bool
|
Recurse bool
|
||||||
// Reverse iterates in reverse order
|
|
||||||
Reverse bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterator iterates over a sequence of ListItems
|
// Iterator iterates over a sequence of ListItems
|
||||||
|
@ -60,26 +60,6 @@ func SortAndCollapse(items Items, prefix []byte) Items {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReverseItems reverses items in the list
|
|
||||||
// items will be reused and modified
|
|
||||||
// TODO: remove this
|
|
||||||
func ReverseItems(items Items) Items {
|
|
||||||
for i := len(items)/2 - 1; i >= 0; i-- {
|
|
||||||
k := len(items) - 1 - i
|
|
||||||
items[i], items[k] = items[k], items[i]
|
|
||||||
}
|
|
||||||
return items
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReverseKeys reverses the list of keys
|
|
||||||
func ReverseKeys(keys Keys) Keys {
|
|
||||||
for i := len(keys)/2 - 1; i >= 0; i-- {
|
|
||||||
k := len(keys) - 1 - i
|
|
||||||
keys[i], keys[k] = keys[k], keys[i]
|
|
||||||
}
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
|
|
||||||
// StaticIterator implements an iterator over list of items
|
// StaticIterator implements an iterator over list of items
|
||||||
type StaticIterator struct {
|
type StaticIterator struct {
|
||||||
Items Items
|
Items Items
|
||||||
|
@ -5,14 +5,12 @@ package storage
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ListOptions are items that are optional for the LIST method
|
// ListOptions are items that are optional for the LIST method
|
||||||
type ListOptions struct {
|
type ListOptions struct {
|
||||||
Prefix Key
|
Prefix Key
|
||||||
StartAfter Key // StartAfter is relative to Prefix
|
StartAfter Key // StartAfter is relative to Prefix
|
||||||
EndBefore Key // EndBefore is relative to Prefix
|
|
||||||
Recursive bool
|
Recursive bool
|
||||||
IncludeValue bool
|
IncludeValue bool
|
||||||
Limit int
|
Limit int
|
||||||
@ -24,12 +22,9 @@ type ListOptions struct {
|
|||||||
// more indicates if the result was truncated. If false
|
// more indicates if the result was truncated. If false
|
||||||
// then the result []ListItem includes all requested keys.
|
// then the result []ListItem includes all requested keys.
|
||||||
// If true then the caller must call List again to get more
|
// If true then the caller must call List again to get more
|
||||||
// results by setting `StartAfter` or `EndBefore` appropriately.
|
// results by setting `StartAfter` appropriately.
|
||||||
func ListV2(ctx context.Context, store KeyValueStore, opts ListOptions) (result Items, more bool, err error) {
|
func ListV2(ctx context.Context, store KeyValueStore, opts ListOptions) (result Items, more bool, err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
if !opts.StartAfter.IsZero() && !opts.EndBefore.IsZero() {
|
|
||||||
return nil, false, errors.New("start-after and end-before cannot be combined")
|
|
||||||
}
|
|
||||||
|
|
||||||
limit := opts.Limit
|
limit := opts.Limit
|
||||||
if limit <= 0 || limit > LookupLimit {
|
if limit <= 0 || limit > LookupLimit {
|
||||||
@ -37,15 +32,8 @@ func ListV2(ctx context.Context, store KeyValueStore, opts ListOptions) (result
|
|||||||
}
|
}
|
||||||
|
|
||||||
more = true
|
more = true
|
||||||
reverse := !opts.EndBefore.IsZero()
|
|
||||||
|
|
||||||
var first Key
|
|
||||||
if !reverse {
|
|
||||||
first = opts.StartAfter
|
|
||||||
} else {
|
|
||||||
first = opts.EndBefore
|
|
||||||
}
|
|
||||||
|
|
||||||
|
first := opts.StartAfter
|
||||||
iterate := func(ctx context.Context, it Iterator) error {
|
iterate := func(ctx context.Context, it Iterator) error {
|
||||||
var item ListItem
|
var item ListItem
|
||||||
skipFirst := true
|
skipFirst := true
|
||||||
@ -86,23 +74,15 @@ func ListV2(ctx context.Context, store KeyValueStore, opts ListOptions) (result
|
|||||||
}
|
}
|
||||||
|
|
||||||
var firstFull Key
|
var firstFull Key
|
||||||
if !reverse && !opts.StartAfter.IsZero() {
|
if !opts.StartAfter.IsZero() {
|
||||||
firstFull = joinKey(opts.Prefix, opts.StartAfter)
|
firstFull = joinKey(opts.Prefix, opts.StartAfter)
|
||||||
}
|
}
|
||||||
if reverse && !opts.EndBefore.IsZero() {
|
|
||||||
firstFull = joinKey(opts.Prefix, opts.EndBefore)
|
|
||||||
}
|
|
||||||
err = store.Iterate(ctx, IterateOptions{
|
err = store.Iterate(ctx, IterateOptions{
|
||||||
Prefix: opts.Prefix,
|
Prefix: opts.Prefix,
|
||||||
First: firstFull,
|
First: firstFull,
|
||||||
Reverse: reverse,
|
|
||||||
Recurse: opts.Recursive,
|
Recurse: opts.Recursive,
|
||||||
}, iterate)
|
}, iterate)
|
||||||
|
|
||||||
if reverse {
|
|
||||||
result = ReverseItems(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, more, err
|
return result, more, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,29 +57,6 @@ FROM (
|
|||||||
) x
|
) x
|
||||||
ORDER BY p
|
ORDER BY p
|
||||||
LIMIT $4
|
LIMIT $4
|
||||||
`
|
|
||||||
|
|
||||||
alternateReverseQuery = `
|
|
||||||
SELECT DISTINCT
|
|
||||||
$2::BYTEA || x.localpath AS p,
|
|
||||||
first_value(x.metadata) OVER (PARTITION BY x.localpath ORDER BY x.fullpath) AS m
|
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
pd.fullpath,
|
|
||||||
local_path(pd.fullpath, $2::BYTEA, set_byte(' '::BYTEA, 0, b.delim)) AS localpath,
|
|
||||||
pd.metadata
|
|
||||||
FROM
|
|
||||||
pathdata pd,
|
|
||||||
buckets b
|
|
||||||
WHERE
|
|
||||||
b.bucketname = $1::BYTEA
|
|
||||||
AND pd.bucket = b.bucketname
|
|
||||||
AND pd.fullpath >= $2::BYTEA
|
|
||||||
AND ($2::BYTEA = ''::BYTEA OR pd.fullpath < bytea_increment($2::BYTEA))
|
|
||||||
AND ($3::BYTEA = ''::BYTEA OR pd.fullpath <= $3::BYTEA)
|
|
||||||
) x
|
|
||||||
ORDER BY p DESC
|
|
||||||
LIMIT $4
|
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -120,13 +97,7 @@ func (opi *alternateOrderedPostgresIterator) doNextQuery(ctx context.Context) (_
|
|||||||
if start == nil {
|
if start == nil {
|
||||||
start = opi.opts.First
|
start = opi.opts.First
|
||||||
}
|
}
|
||||||
var query string
|
return opi.client.pgConn.Query(alternateForwardQuery, []byte(opi.bucket), []byte(opi.opts.Prefix), []byte(start), opi.batchSize+1)
|
||||||
if opi.opts.Reverse {
|
|
||||||
query = alternateReverseQuery
|
|
||||||
} else {
|
|
||||||
query = alternateForwardQuery
|
|
||||||
}
|
|
||||||
return opi.client.pgConn.Query(query, []byte(opi.bucket), []byte(opi.opts.Prefix), []byte(start), opi.batchSize+1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAlternateOrderedPostgresIterator(ctx context.Context, altClient *AlternateClient, opts storage.IterateOptions, batchSize int) (_ *alternateOrderedPostgresIterator, err error) {
|
func newAlternateOrderedPostgresIterator(ctx context.Context, altClient *AlternateClient, opts storage.IterateOptions, batchSize int) (_ *alternateOrderedPostgresIterator, err error) {
|
||||||
|
@ -6,7 +6,6 @@ package postgreskv
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
"github.com/zeebo/errs"
|
"github.com/zeebo/errs"
|
||||||
@ -254,28 +253,18 @@ func (opi *orderedPostgresIterator) doNextQuery(ctx context.Context) (_ *sql.Row
|
|||||||
}
|
}
|
||||||
var query string
|
var query string
|
||||||
if !opi.opts.Recurse {
|
if !opi.opts.Recurse {
|
||||||
if opi.opts.Reverse {
|
|
||||||
query = "SELECT p, m FROM list_directory_reverse($1::BYTEA, $2::BYTEA, $3::BYTEA, $4) ld(p, m)"
|
|
||||||
} else {
|
|
||||||
query = "SELECT p, m FROM list_directory($1::BYTEA, $2::BYTEA, $3::BYTEA, $4) ld(p, m)"
|
query = "SELECT p, m FROM list_directory($1::BYTEA, $2::BYTEA, $3::BYTEA, $4) ld(p, m)"
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
startCmp := ">="
|
query = `
|
||||||
orderDir := ""
|
|
||||||
if opi.opts.Reverse {
|
|
||||||
startCmp = "<="
|
|
||||||
orderDir = " DESC"
|
|
||||||
}
|
|
||||||
query = fmt.Sprintf(`
|
|
||||||
SELECT fullpath, metadata
|
SELECT fullpath, metadata
|
||||||
FROM pathdata
|
FROM pathdata
|
||||||
WHERE bucket = $1::BYTEA
|
WHERE bucket = $1::BYTEA
|
||||||
AND ($2::BYTEA = ''::BYTEA OR fullpath >= $2::BYTEA)
|
AND ($2::BYTEA = ''::BYTEA OR fullpath >= $2::BYTEA)
|
||||||
AND ($2::BYTEA = ''::BYTEA OR fullpath < bytea_increment($2::BYTEA))
|
AND ($2::BYTEA = ''::BYTEA OR fullpath < bytea_increment($2::BYTEA))
|
||||||
AND ($3::BYTEA = ''::BYTEA OR fullpath %s $3::BYTEA)
|
AND ($3::BYTEA = ''::BYTEA OR fullpath >= $3::BYTEA)
|
||||||
ORDER BY fullpath%s
|
ORDER BY fullpath
|
||||||
LIMIT $4
|
LIMIT $4
|
||||||
`, startCmp, orderDir)
|
`
|
||||||
}
|
}
|
||||||
return opi.client.pgConn.Query(query, []byte(opi.bucket), []byte(opi.opts.Prefix), []byte(start), opi.batchSize+1)
|
return opi.client.pgConn.Query(query, []byte(opi.bucket), []byte(opi.opts.Prefix), []byte(start), opi.batchSize+1)
|
||||||
}
|
}
|
||||||
|
@ -164,21 +164,13 @@ func (client *Client) GetAll(ctx context.Context, keys storage.Keys) (_ storage.
|
|||||||
// Iterate iterates over items based on opts
|
// Iterate iterates over items based on opts
|
||||||
func (client *Client) Iterate(ctx context.Context, opts storage.IterateOptions, fn func(context.Context, storage.Iterator) error) (err error) {
|
func (client *Client) Iterate(ctx context.Context, opts storage.IterateOptions, fn func(context.Context, storage.Iterator) error) (err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
var all storage.Items
|
all, err := client.allPrefixedItems(opts.Prefix, opts.First, nil)
|
||||||
if !opts.Reverse {
|
|
||||||
all, err = client.allPrefixedItems(opts.Prefix, opts.First, nil)
|
|
||||||
} else {
|
|
||||||
all, err = client.allPrefixedItems(opts.Prefix, nil, opts.First)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !opts.Recurse {
|
if !opts.Recurse {
|
||||||
all = storage.SortAndCollapse(all, opts.Prefix)
|
all = storage.SortAndCollapse(all, opts.Prefix)
|
||||||
}
|
}
|
||||||
if opts.Reverse {
|
|
||||||
all = storage.ReverseItems(all)
|
|
||||||
}
|
|
||||||
return fn(ctx, &storage.StaticIterator{
|
return fn(ctx, &storage.StaticIterator{
|
||||||
Items: all,
|
Items: all,
|
||||||
})
|
})
|
||||||
|
@ -74,7 +74,6 @@ func (store *Logger) Iterate(ctx context.Context, opts storage.IterateOptions, f
|
|||||||
zap.ByteString("prefix", opts.Prefix),
|
zap.ByteString("prefix", opts.Prefix),
|
||||||
zap.ByteString("first", opts.First),
|
zap.ByteString("first", opts.First),
|
||||||
zap.Bool("recurse", opts.Recurse),
|
zap.Bool("recurse", opts.Recurse),
|
||||||
zap.Bool("reverse", opts.Reverse),
|
|
||||||
)
|
)
|
||||||
return store.store.Iterate(ctx, opts, func(ctx context.Context, it storage.Iterator) error {
|
return store.store.Iterate(ctx, opts, func(ctx context.Context, it storage.Iterator) error {
|
||||||
return fn(ctx, storage.IteratorFunc(func(ctx context.Context, item *storage.ListItem) bool {
|
return fn(ctx, storage.IteratorFunc(func(ctx context.Context, item *storage.ListItem) bool {
|
||||||
|
@ -30,7 +30,6 @@ type Client struct {
|
|||||||
Put int
|
Put int
|
||||||
List int
|
List int
|
||||||
GetAll int
|
GetAll int
|
||||||
ReverseList int
|
|
||||||
Delete int
|
Delete int
|
||||||
Close int
|
Close int
|
||||||
Iterate int
|
Iterate int
|
||||||
@ -202,12 +201,7 @@ func (store *Client) Iterate(ctx context.Context, opts storage.IterateOptions, f
|
|||||||
return errInternal
|
return errInternal
|
||||||
}
|
}
|
||||||
|
|
||||||
var cursor advancer
|
var cursor advancer = &forward{newCursor(store)}
|
||||||
if !opts.Reverse {
|
|
||||||
cursor = &forward{newCursor(store)}
|
|
||||||
} else {
|
|
||||||
cursor = &backward{newCursor(store)}
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor.PositionToFirst(opts.Prefix, opts.First)
|
cursor.PositionToFirst(opts.Prefix, opts.First)
|
||||||
var lastPrefix storage.Key
|
var lastPrefix storage.Key
|
||||||
|
@ -194,19 +194,12 @@ func BenchmarkPathOperationsInLargeDb(b *testing.B, store storage.KeyValueStore)
|
|||||||
}
|
}
|
||||||
|
|
||||||
doTest("DeepRecursive", deepRecursive)
|
doTest("DeepRecursive", deepRecursive)
|
||||||
doTest("DeepRecursiveReverse", deepRecursiveReverse)
|
|
||||||
doTest("DeepNonRecursive", deepNonRecursive)
|
doTest("DeepNonRecursive", deepNonRecursive)
|
||||||
doTest("DeepNonRecursiveReverse", deepNonRecursiveReverse)
|
|
||||||
doTest("ShallowRecursive", shallowRecursive)
|
doTest("ShallowRecursive", shallowRecursive)
|
||||||
doTest("ShallowRecursiveReverse", shallowRecursiveReverse)
|
|
||||||
doTest("ShallowNonRecursive", shallowNonRecursive)
|
doTest("ShallowNonRecursive", shallowNonRecursive)
|
||||||
doTest("ShallowNonRecursiveReverse", shallowNonRecursiveReverse)
|
|
||||||
doTest("TopRecursiveLimit", topRecursiveLimit)
|
doTest("TopRecursiveLimit", topRecursiveLimit)
|
||||||
doTest("TopRecursiveLimitReverse", topRecursiveLimitReverse)
|
|
||||||
doTest("TopRecursiveStartAt", topRecursiveStartAt)
|
doTest("TopRecursiveStartAt", topRecursiveStartAt)
|
||||||
doTest("TopRecursiveStartAtReverse", topRecursiveStartAtReverse)
|
|
||||||
doTest("TopNonRecursive", topNonRecursive)
|
doTest("TopNonRecursive", topNonRecursive)
|
||||||
doTest("TopNonRecursiveReverse", topNonRecursiveReverse)
|
|
||||||
|
|
||||||
cleanupStore(b, store)
|
cleanupStore(b, store)
|
||||||
}
|
}
|
||||||
@ -347,10 +340,7 @@ func benchAndVerifyIteration(b *testing.B, store storage.KeyValueStore, opts *ve
|
|||||||
if result.Key.Equal(lastKey) {
|
if result.Key.Equal(lastKey) {
|
||||||
errorf("got the same key (%q) twice in a row, not on a lookup boundary!", lastKey)
|
errorf("got the same key (%q) twice in a row, not on a lookup boundary!", lastKey)
|
||||||
}
|
}
|
||||||
if opts.iterateOpts.Reverse && !lastKey.IsZero() && lastKey.Less(result.Key) {
|
if result.Key.Less(lastKey) {
|
||||||
errorf("KeyValueStore returned items out of order! %q > %q", result.Key, lastKey)
|
|
||||||
}
|
|
||||||
if !opts.iterateOpts.Reverse && result.Key.Less(lastKey) {
|
|
||||||
errorf("KeyValueStore returned items out of order! %q < %q", result.Key, lastKey)
|
errorf("KeyValueStore returned items out of order! %q < %q", result.Key, lastKey)
|
||||||
}
|
}
|
||||||
if result.IsPrefix {
|
if result.IsPrefix {
|
||||||
@ -410,31 +400,6 @@ func deepRecursive(b *testing.B, store storage.KeyValueStore) {
|
|||||||
benchAndVerifyIteration(b, store, opts)
|
benchAndVerifyIteration(b, store, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deepRecursiveReverse(b *testing.B, store storage.KeyValueStore) {
|
|
||||||
opts := &verifyOpts{
|
|
||||||
iterateOpts: storage.IterateOptions{
|
|
||||||
Prefix: storage.Key(largestLevel2Directory),
|
|
||||||
Recurse: true,
|
|
||||||
Reverse: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// these are not expected to exhaust all available items
|
|
||||||
opts.doIterations = 500
|
|
||||||
opts.batchSize = storage.LookupLimit
|
|
||||||
opts.expectCount = opts.doIterations * opts.batchSize
|
|
||||||
|
|
||||||
// verify with:
|
|
||||||
// select encode(fullpath, 'escape') from (
|
|
||||||
// select rank() over (order by fullpath desc), fullpath from pathdata
|
|
||||||
// where fullpath < bytea_increment($1::bytea)
|
|
||||||
// ) x where rank = ($2 * $3);
|
|
||||||
// where $1 = largestLevel2Directory, $2 = doIterations, and $3 = batchSize
|
|
||||||
opts.expectLastKey = storage.Key("Peronosporales/hateless/apetaly/poikilocythemia/capped/abrash/dugout/notodontid/jasponyx/cassican/brunelliaceous")
|
|
||||||
|
|
||||||
benchAndVerifyIteration(b, store, opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func deepNonRecursive(b *testing.B, store storage.KeyValueStore) {
|
func deepNonRecursive(b *testing.B, store storage.KeyValueStore) {
|
||||||
opts := &verifyOpts{
|
opts := &verifyOpts{
|
||||||
iterateOpts: storage.IterateOptions{
|
iterateOpts: storage.IterateOptions{
|
||||||
@ -460,32 +425,6 @@ func deepNonRecursive(b *testing.B, store storage.KeyValueStore) {
|
|||||||
benchAndVerifyIteration(b, store, opts)
|
benchAndVerifyIteration(b, store, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deepNonRecursiveReverse(b *testing.B, store storage.KeyValueStore) {
|
|
||||||
opts := &verifyOpts{
|
|
||||||
iterateOpts: storage.IterateOptions{
|
|
||||||
Prefix: storage.Key(largestLevel2Directory),
|
|
||||||
Recurse: false,
|
|
||||||
Reverse: true,
|
|
||||||
},
|
|
||||||
doIterations: 1,
|
|
||||||
batchSize: 10000,
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify with:
|
|
||||||
// select count(*) from list_directory(''::bytea, $1::bytea) ld(fp, md);
|
|
||||||
// where $1 is largestLevel2Directory
|
|
||||||
opts.expectCount = 119
|
|
||||||
|
|
||||||
// verify with:
|
|
||||||
// select encode(fp, 'escape') from (
|
|
||||||
// select * from list_directory(''::bytea, $1::bytea) ld(fp, md)
|
|
||||||
// ) x order by fp limit 1;
|
|
||||||
// where $1 is largestLevel2Directory
|
|
||||||
opts.expectLastKey = storage.Key("Peronosporales/hateless/Absyrtus")
|
|
||||||
|
|
||||||
benchAndVerifyIteration(b, store, opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func shallowRecursive(b *testing.B, store storage.KeyValueStore) {
|
func shallowRecursive(b *testing.B, store storage.KeyValueStore) {
|
||||||
opts := &verifyOpts{
|
opts := &verifyOpts{
|
||||||
iterateOpts: storage.IterateOptions{
|
iterateOpts: storage.IterateOptions{
|
||||||
@ -515,36 +454,6 @@ func shallowRecursive(b *testing.B, store storage.KeyValueStore) {
|
|||||||
benchAndVerifyIteration(b, store, opts)
|
benchAndVerifyIteration(b, store, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func shallowRecursiveReverse(b *testing.B, store storage.KeyValueStore) {
|
|
||||||
opts := &verifyOpts{
|
|
||||||
iterateOpts: storage.IterateOptions{
|
|
||||||
Prefix: storage.Key(largestSingleDirectory),
|
|
||||||
Recurse: true,
|
|
||||||
Reverse: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify with:
|
|
||||||
// select count(*) from pathdata
|
|
||||||
// where fullpath > $1::bytea and fullpath < bytea_increment($1::bytea);
|
|
||||||
// where $1 = largestSingleDirectory
|
|
||||||
opts.expectCount = 18574
|
|
||||||
|
|
||||||
// verify with:
|
|
||||||
// select convert_from(fullpath, 'UTF8') from pathdata
|
|
||||||
// where fullpath > $1::bytea and fullpath < bytea_increment($1::bytea)
|
|
||||||
// order by fullpath limit 1;
|
|
||||||
// where $1 = largestSingleDirectory
|
|
||||||
opts.expectLastKey = storage.Key("Peronosporales/hateless/tod/unricht/sniveling/Puyallup/Aaronite")
|
|
||||||
|
|
||||||
// i didn't plan it this way, but expectedCount happens to have some nicely-sized factors for
|
|
||||||
// our purposes with no messy remainder. 74 * 251 = 18574
|
|
||||||
opts.doIterations = 74
|
|
||||||
opts.batchSize = 251
|
|
||||||
|
|
||||||
benchAndVerifyIteration(b, store, opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func shallowNonRecursive(b *testing.B, store storage.KeyValueStore) {
|
func shallowNonRecursive(b *testing.B, store storage.KeyValueStore) {
|
||||||
opts := &verifyOpts{
|
opts := &verifyOpts{
|
||||||
iterateOpts: storage.IterateOptions{
|
iterateOpts: storage.IterateOptions{
|
||||||
@ -570,32 +479,6 @@ func shallowNonRecursive(b *testing.B, store storage.KeyValueStore) {
|
|||||||
benchAndVerifyIteration(b, store, opts)
|
benchAndVerifyIteration(b, store, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func shallowNonRecursiveReverse(b *testing.B, store storage.KeyValueStore) {
|
|
||||||
opts := &verifyOpts{
|
|
||||||
iterateOpts: storage.IterateOptions{
|
|
||||||
Prefix: storage.Key(largestSingleDirectory),
|
|
||||||
Recurse: false,
|
|
||||||
Reverse: true,
|
|
||||||
},
|
|
||||||
doIterations: 2,
|
|
||||||
batchSize: 10000,
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify with:
|
|
||||||
// select count(*) from list_directory(''::bytea, $1::bytea) ld(fp, md);
|
|
||||||
// where $1 is largestSingleDirectory
|
|
||||||
opts.expectCount = 18574
|
|
||||||
|
|
||||||
// verify with:
|
|
||||||
// select encode(fp, 'escape') from (
|
|
||||||
// select * from list_directory(''::bytea, $1::bytea) ld(fp, md)
|
|
||||||
// ) x order by fp limit 1;
|
|
||||||
// where $1 = largestSingleDirectory
|
|
||||||
opts.expectLastKey = storage.Key("Peronosporales/hateless/tod/unricht/sniveling/Puyallup/Aaronite")
|
|
||||||
|
|
||||||
benchAndVerifyIteration(b, store, opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func topRecursiveLimit(b *testing.B, store storage.KeyValueStore) {
|
func topRecursiveLimit(b *testing.B, store storage.KeyValueStore) {
|
||||||
opts := &verifyOpts{
|
opts := &verifyOpts{
|
||||||
iterateOpts: storage.IterateOptions{
|
iterateOpts: storage.IterateOptions{
|
||||||
@ -618,29 +501,6 @@ func topRecursiveLimit(b *testing.B, store storage.KeyValueStore) {
|
|||||||
benchAndVerifyIteration(b, store, opts)
|
benchAndVerifyIteration(b, store, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func topRecursiveLimitReverse(b *testing.B, store storage.KeyValueStore) {
|
|
||||||
opts := &verifyOpts{
|
|
||||||
iterateOpts: storage.IterateOptions{
|
|
||||||
Recurse: true,
|
|
||||||
Reverse: true,
|
|
||||||
},
|
|
||||||
doIterations: 100,
|
|
||||||
batchSize: 10000,
|
|
||||||
}
|
|
||||||
|
|
||||||
// not expected to exhaust items
|
|
||||||
opts.expectCount = opts.doIterations * opts.batchSize
|
|
||||||
|
|
||||||
// verify with:
|
|
||||||
// select encode(fullpath, 'escape') from (
|
|
||||||
// select rank() over (order by fullpath desc), fullpath from pathdata
|
|
||||||
// ) x where rank = $1;
|
|
||||||
// where $1 = expectCount
|
|
||||||
opts.expectLastKey = storage.Key("nonresuscitation/synchronically/cabook/homeozoic/inclinatorium/iguanodont/thiophenol/congeliturbation/Alaric")
|
|
||||||
|
|
||||||
benchAndVerifyIteration(b, store, opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func topRecursiveStartAt(b *testing.B, store storage.KeyValueStore) {
|
func topRecursiveStartAt(b *testing.B, store storage.KeyValueStore) {
|
||||||
opts := &verifyOpts{
|
opts := &verifyOpts{
|
||||||
iterateOpts: storage.IterateOptions{
|
iterateOpts: storage.IterateOptions{
|
||||||
@ -666,36 +526,6 @@ func topRecursiveStartAt(b *testing.B, store storage.KeyValueStore) {
|
|||||||
benchAndVerifyIteration(b, store, opts)
|
benchAndVerifyIteration(b, store, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func topRecursiveStartAtReverse(b *testing.B, store storage.KeyValueStore) {
|
|
||||||
opts := &verifyOpts{
|
|
||||||
iterateOpts: storage.IterateOptions{
|
|
||||||
Recurse: true,
|
|
||||||
Reverse: true,
|
|
||||||
},
|
|
||||||
doIterations: 61,
|
|
||||||
batchSize: 10000,
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is pretty arbitrary. just the key 100 positions before the end of the Peronosporales/hateless/ dir.
|
|
||||||
opts.iterateOpts.First = storage.Key("Peronosporales/hateless/warrener/anthropomancy/geisotherm/wickerwork")
|
|
||||||
|
|
||||||
// we *do* expect to exhaust the available items this time.
|
|
||||||
// verify with:
|
|
||||||
// select count(*) from (
|
|
||||||
// select fullpath from pathdata where fullpath <= $1::bytea order by fullpath desc limit $2
|
|
||||||
// ) x;
|
|
||||||
// where $1 = iterateOpts.First and $2 = (doIterations * batchSize)
|
|
||||||
opts.expectCount = 608405
|
|
||||||
|
|
||||||
// since expectCount < (doIterations * batchSize), and we're going in reverse, the last key read
|
|
||||||
// should be the first one lexicographically.
|
|
||||||
// verify with:
|
|
||||||
// select encode(fullpath, 'escape') from pathdata order by fullpath limit 1;
|
|
||||||
opts.expectLastKey = storage.Key("Lissamphibia")
|
|
||||||
|
|
||||||
benchAndVerifyIteration(b, store, opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func topNonRecursive(b *testing.B, store storage.KeyValueStore) {
|
func topNonRecursive(b *testing.B, store storage.KeyValueStore) {
|
||||||
opts := &verifyOpts{
|
opts := &verifyOpts{
|
||||||
iterateOpts: storage.IterateOptions{
|
iterateOpts: storage.IterateOptions{
|
||||||
@ -718,27 +548,6 @@ func topNonRecursive(b *testing.B, store storage.KeyValueStore) {
|
|||||||
benchAndVerifyIteration(b, store, opts)
|
benchAndVerifyIteration(b, store, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func topNonRecursiveReverse(b *testing.B, store storage.KeyValueStore) {
|
|
||||||
opts := &verifyOpts{
|
|
||||||
iterateOpts: storage.IterateOptions{
|
|
||||||
Recurse: false,
|
|
||||||
Reverse: true,
|
|
||||||
},
|
|
||||||
doIterations: 1,
|
|
||||||
batchSize: 10000,
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify with:
|
|
||||||
// select count(*) from list_directory(''::bytea, ''::bytea);
|
|
||||||
opts.expectCount = 21
|
|
||||||
|
|
||||||
// verify with:
|
|
||||||
// select encode(fullpath, 'escape') from pathdata order by fullpath limit 1;
|
|
||||||
opts.expectLastKey = storage.Key("Lissamphibia")
|
|
||||||
|
|
||||||
benchAndVerifyIteration(b, store, opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func cleanupBigPathset(tb testing.TB, store storage.KeyValueStore) {
|
func cleanupBigPathset(tb testing.TB, store storage.KeyValueStore) {
|
||||||
if *noCleanDb {
|
if *noCleanDb {
|
||||||
tb.Skip("Instructed not to clean up this KeyValueStore after long benchmarks are complete.")
|
tb.Skip("Instructed not to clean up this KeyValueStore after long benchmarks are complete.")
|
||||||
|
@ -42,17 +42,6 @@ func testIterate(t *testing.T, store storage.KeyValueStore) {
|
|||||||
newItem("g", "g", false),
|
newItem("g", "g", false),
|
||||||
newItem("h", "h", false),
|
newItem("h", "h", false),
|
||||||
}},
|
}},
|
||||||
{"no limits reverse",
|
|
||||||
storage.IterateOptions{
|
|
||||||
Reverse: true,
|
|
||||||
}, storage.Items{
|
|
||||||
newItem("h", "h", false),
|
|
||||||
newItem("g", "g", false),
|
|
||||||
newItem("c/", "", true),
|
|
||||||
newItem("c", "c", false),
|
|
||||||
newItem("b/", "", true),
|
|
||||||
newItem("a", "a", false),
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"at a",
|
{"at a",
|
||||||
storage.IterateOptions{
|
storage.IterateOptions{
|
||||||
@ -66,14 +55,6 @@ func testIterate(t *testing.T, store storage.KeyValueStore) {
|
|||||||
newItem("h", "h", false),
|
newItem("h", "h", false),
|
||||||
}},
|
}},
|
||||||
|
|
||||||
{"reverse at a",
|
|
||||||
storage.IterateOptions{
|
|
||||||
First: storage.Key("a"),
|
|
||||||
Reverse: true,
|
|
||||||
}, storage.Items{
|
|
||||||
newItem("a", "a", false),
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"after a",
|
{"after a",
|
||||||
storage.IterateOptions{
|
storage.IterateOptions{
|
||||||
First: storage.NextKey(storage.Key("a")),
|
First: storage.NextKey(storage.Key("a")),
|
||||||
@ -126,16 +107,6 @@ func testIterate(t *testing.T, store storage.KeyValueStore) {
|
|||||||
newItem("g", "g", false),
|
newItem("g", "g", false),
|
||||||
newItem("h", "h", false),
|
newItem("h", "h", false),
|
||||||
}},
|
}},
|
||||||
{"reverse after e",
|
|
||||||
storage.IterateOptions{
|
|
||||||
First: storage.NextKey(storage.Key("e")),
|
|
||||||
Reverse: true,
|
|
||||||
}, storage.Items{
|
|
||||||
newItem("c/", "", true),
|
|
||||||
newItem("c", "c", false),
|
|
||||||
newItem("b/", "", true),
|
|
||||||
newItem("a", "a", false),
|
|
||||||
}},
|
|
||||||
{"prefix b slash",
|
{"prefix b slash",
|
||||||
storage.IterateOptions{
|
storage.IterateOptions{
|
||||||
Prefix: storage.Key("b/"),
|
Prefix: storage.Key("b/"),
|
||||||
|
@ -61,21 +61,6 @@ func testIterateAll(t *testing.T, store storage.KeyValueStore) {
|
|||||||
newItem("g", "g", false),
|
newItem("g", "g", false),
|
||||||
newItem("h", "h", false),
|
newItem("h", "h", false),
|
||||||
}},
|
}},
|
||||||
{"no limits reverse",
|
|
||||||
storage.IterateOptions{
|
|
||||||
Recurse: true, Reverse: true,
|
|
||||||
}, storage.Items{
|
|
||||||
newItem("h", "h", false),
|
|
||||||
newItem("g", "g", false),
|
|
||||||
newItem("c/1", "c/1", false),
|
|
||||||
newItem("c//", "c//", false),
|
|
||||||
newItem("c/", "c/", false),
|
|
||||||
newItem("c", "c", false),
|
|
||||||
newItem("b/3", "b/3", false),
|
|
||||||
newItem("b/2", "b/2", false),
|
|
||||||
newItem("b/1", "b/1", false),
|
|
||||||
newItem("a", "a", false),
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"at a",
|
{"at a",
|
||||||
storage.IterateOptions{
|
storage.IterateOptions{
|
||||||
@ -93,13 +78,6 @@ func testIterateAll(t *testing.T, store storage.KeyValueStore) {
|
|||||||
newItem("g", "g", false),
|
newItem("g", "g", false),
|
||||||
newItem("h", "h", false),
|
newItem("h", "h", false),
|
||||||
}},
|
}},
|
||||||
{"at a reverse",
|
|
||||||
storage.IterateOptions{
|
|
||||||
First: storage.Key("a"),
|
|
||||||
Recurse: true, Reverse: true,
|
|
||||||
}, storage.Items{
|
|
||||||
newItem("a", "a", false),
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"after a",
|
{"after a",
|
||||||
storage.IterateOptions{
|
storage.IterateOptions{
|
||||||
@ -180,20 +158,6 @@ func testIterateAll(t *testing.T, store storage.KeyValueStore) {
|
|||||||
newItem("g", "g", false),
|
newItem("g", "g", false),
|
||||||
newItem("h", "h", false),
|
newItem("h", "h", false),
|
||||||
}},
|
}},
|
||||||
{"at e reverse",
|
|
||||||
storage.IterateOptions{
|
|
||||||
First: storage.Key("e"),
|
|
||||||
Recurse: true, Reverse: true,
|
|
||||||
}, storage.Items{
|
|
||||||
newItem("c/1", "c/1", false),
|
|
||||||
newItem("c//", "c//", false),
|
|
||||||
newItem("c/", "c/", false),
|
|
||||||
newItem("c", "c", false),
|
|
||||||
newItem("b/3", "b/3", false),
|
|
||||||
newItem("b/2", "b/2", false),
|
|
||||||
newItem("b/1", "b/1", false),
|
|
||||||
newItem("a", "a", false),
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"prefix b slash",
|
{"prefix b slash",
|
||||||
storage.IterateOptions{
|
storage.IterateOptions{
|
||||||
@ -221,23 +185,6 @@ func testIterateAll(t *testing.T, store storage.KeyValueStore) {
|
|||||||
newItem("b/2", "b/2", false),
|
newItem("b/2", "b/2", false),
|
||||||
newItem("b/3", "b/3", false),
|
newItem("b/3", "b/3", false),
|
||||||
}},
|
}},
|
||||||
{"reverse prefix b slash",
|
|
||||||
storage.IterateOptions{
|
|
||||||
Prefix: storage.Key("b/"),
|
|
||||||
Recurse: true, Reverse: true,
|
|
||||||
}, storage.Items{
|
|
||||||
newItem("b/3", "b/3", false),
|
|
||||||
newItem("b/2", "b/2", false),
|
|
||||||
newItem("b/1", "b/1", false),
|
|
||||||
}},
|
|
||||||
{"reverse prefix b slash at b slash 2",
|
|
||||||
storage.IterateOptions{
|
|
||||||
Prefix: storage.Key("b/"), First: storage.Key("b/2"),
|
|
||||||
Recurse: true, Reverse: true,
|
|
||||||
}, storage.Items{
|
|
||||||
newItem("b/2", "b/2", false),
|
|
||||||
newItem("b/1", "b/1", false),
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"prefix c slash",
|
{"prefix c slash",
|
||||||
storage.IterateOptions{
|
storage.IterateOptions{
|
||||||
@ -248,15 +195,6 @@ func testIterateAll(t *testing.T, store storage.KeyValueStore) {
|
|||||||
newItem("c//", "c//", false),
|
newItem("c//", "c//", false),
|
||||||
newItem("c/1", "c/1", false),
|
newItem("c/1", "c/1", false),
|
||||||
}},
|
}},
|
||||||
{"reverse prefix c slash",
|
|
||||||
storage.IterateOptions{
|
|
||||||
Prefix: storage.Key("c/"),
|
|
||||||
Recurse: true, Reverse: true,
|
|
||||||
}, storage.Items{
|
|
||||||
newItem("c/1", "c/1", false),
|
|
||||||
newItem("c//", "c//", false),
|
|
||||||
newItem("c/", "c/", false),
|
|
||||||
}},
|
|
||||||
|
|
||||||
{"prefix c slash slash",
|
{"prefix c slash slash",
|
||||||
storage.IterateOptions{
|
storage.IterateOptions{
|
||||||
@ -265,12 +203,5 @@ func testIterateAll(t *testing.T, store storage.KeyValueStore) {
|
|||||||
}, storage.Items{
|
}, storage.Items{
|
||||||
newItem("c//", "c//", false),
|
newItem("c//", "c//", false),
|
||||||
}},
|
}},
|
||||||
{"reverse prefix c slash slash",
|
|
||||||
storage.IterateOptions{
|
|
||||||
Prefix: storage.Key("c//"),
|
|
||||||
Recurse: true, Reverse: true,
|
|
||||||
}, storage.Items{
|
|
||||||
newItem("c//", "c//", false),
|
|
||||||
}},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -122,49 +122,6 @@ func testListV2(t *testing.T, store storage.KeyValueStore) {
|
|||||||
newItem("my-album/", "", true),
|
newItem("my-album/", "", true),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{"end before 2 recursive",
|
|
||||||
storage.ListOptions{
|
|
||||||
Recursive: true,
|
|
||||||
EndBefore: storage.Key("music/z-song5.mp3"),
|
|
||||||
Limit: 2,
|
|
||||||
},
|
|
||||||
true, storage.Items{
|
|
||||||
newItem("music/my-album/song3.mp3", "", false),
|
|
||||||
newItem("music/my-album/song4.mp3", "", false),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{"end before non-existing 2 recursive",
|
|
||||||
storage.ListOptions{
|
|
||||||
Recursive: true,
|
|
||||||
EndBefore: storage.Key("music/my-album/song5.mp3"),
|
|
||||||
Limit: 2,
|
|
||||||
},
|
|
||||||
true, storage.Items{
|
|
||||||
newItem("music/my-album/song3.mp3", "", false),
|
|
||||||
newItem("music/my-album/song4.mp3", "", false),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{"end before 2",
|
|
||||||
storage.ListOptions{
|
|
||||||
Prefix: storage.Key("music/"),
|
|
||||||
EndBefore: storage.Key("z-song5.mp3"),
|
|
||||||
Limit: 2,
|
|
||||||
},
|
|
||||||
true, storage.Items{
|
|
||||||
newItem("a-song2.mp3", "", false),
|
|
||||||
newItem("my-album/", "", true),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{"end before 2 prefixed",
|
|
||||||
storage.ListOptions{
|
|
||||||
Prefix: storage.Key("music/my-album/"),
|
|
||||||
EndBefore: storage.Key("song4.mp3"),
|
|
||||||
Limit: 2,
|
|
||||||
},
|
|
||||||
false, storage.Items{
|
|
||||||
newItem("song3.mp3", "", false),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
@ -39,30 +39,12 @@ func testPrefix(t *testing.T, store storage.KeyValueStore) {
|
|||||||
newItem("x-b/2", "b/2", false),
|
newItem("x-b/2", "b/2", false),
|
||||||
newItem("x-b/3", "b/3", false),
|
newItem("x-b/3", "b/3", false),
|
||||||
}},
|
}},
|
||||||
{"reverse prefix x dash b slash",
|
|
||||||
storage.IterateOptions{
|
|
||||||
Prefix: storage.Key("x-"), First: storage.Key("x-b/3"),
|
|
||||||
Recurse: true, Reverse: true,
|
|
||||||
}, storage.Items{
|
|
||||||
newItem("x-b/3", "b/3", false),
|
|
||||||
newItem("x-b/2", "b/2", false),
|
|
||||||
newItem("x-b/1", "b/1", false),
|
|
||||||
newItem("x-a", "a", false),
|
|
||||||
}},
|
|
||||||
{"prefix x dash b slash",
|
{"prefix x dash b slash",
|
||||||
storage.IterateOptions{
|
storage.IterateOptions{
|
||||||
Prefix: storage.Key("x-"), First: storage.Key("x-b"),
|
Prefix: storage.Key("x-"), First: storage.Key("x-b"),
|
||||||
}, storage.Items{
|
}, storage.Items{
|
||||||
newItem("x-b/", "", true),
|
newItem("x-b/", "", true),
|
||||||
}},
|
}},
|
||||||
{"reverse x dash b slash",
|
|
||||||
storage.IterateOptions{
|
|
||||||
Prefix: storage.Key("x-"), First: storage.Key("x-b/2"),
|
|
||||||
Reverse: true,
|
|
||||||
}, storage.Items{
|
|
||||||
newItem("x-b/", "", true),
|
|
||||||
newItem("x-a", "a", false),
|
|
||||||
}},
|
|
||||||
{"prefix y- slash",
|
{"prefix y- slash",
|
||||||
storage.IterateOptions{
|
storage.IterateOptions{
|
||||||
Prefix: storage.Key("y-"),
|
Prefix: storage.Key("y-"),
|
||||||
|
@ -134,7 +134,7 @@ func (client *Client) DeleteSegmentOld(ctx context.Context, bucket string, path
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListSegmentsOld lists the available segments
|
// ListSegmentsOld lists the available segments
|
||||||
func (client *Client) ListSegmentsOld(ctx context.Context, bucket string, prefix, startAfter, endBefore storj.Path, recursive bool, limit int32, metaFlags uint32) (items []ListItem, more bool, err error) {
|
func (client *Client) ListSegmentsOld(ctx context.Context, bucket string, prefix, startAfter, ignoredEndBefore storj.Path, recursive bool, limit int32, metaFlags uint32) (items []ListItem, more bool, err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
response, err := client.client.ListSegmentsOld(ctx, &pb.ListSegmentsRequestOld{
|
response, err := client.client.ListSegmentsOld(ctx, &pb.ListSegmentsRequestOld{
|
||||||
@ -142,7 +142,6 @@ func (client *Client) ListSegmentsOld(ctx context.Context, bucket string, prefix
|
|||||||
Bucket: []byte(bucket),
|
Bucket: []byte(bucket),
|
||||||
Prefix: []byte(prefix),
|
Prefix: []byte(prefix),
|
||||||
StartAfter: []byte(startAfter),
|
StartAfter: []byte(startAfter),
|
||||||
EndBefore: []byte(endBefore),
|
|
||||||
Recursive: recursive,
|
Recursive: recursive,
|
||||||
Limit: limit,
|
Limit: limit,
|
||||||
MetaFlags: metaFlags,
|
MetaFlags: metaFlags,
|
||||||
|
@ -169,15 +169,9 @@ func (db *DB) ListObjects(ctx context.Context, bucket string, options storj.List
|
|||||||
prefix: bucket,
|
prefix: bucket,
|
||||||
}
|
}
|
||||||
|
|
||||||
var startAfter, endBefore string
|
var startAfter string
|
||||||
switch options.Direction {
|
switch options.Direction {
|
||||||
// TODO for now we are supporting only storj.After
|
// TODO for now we are supporting only storj.After
|
||||||
// case storj.Before:
|
|
||||||
// // before lists backwards from cursor, without cursor
|
|
||||||
// endBefore = options.Cursor
|
|
||||||
// case storj.Backward:
|
|
||||||
// // backward lists backwards from cursor, including cursor
|
|
||||||
// endBefore = keyAfter(options.Cursor)
|
|
||||||
// case storj.Forward:
|
// case storj.Forward:
|
||||||
// // forward lists forwards from cursor, including cursor
|
// // forward lists forwards from cursor, including cursor
|
||||||
// startAfter = keyBefore(options.Cursor)
|
// startAfter = keyBefore(options.Cursor)
|
||||||
@ -188,12 +182,7 @@ func (db *DB) ListObjects(ctx context.Context, bucket string, options storj.List
|
|||||||
return storj.ObjectList{}, errClass.New("invalid direction %d", options.Direction)
|
return storj.ObjectList{}, errClass.New("invalid direction %d", options.Direction)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove this hack-fix of specifying the last key
|
items, more, err := objects.List(ctx, options.Prefix, startAfter, options.Recursive, options.Limit, meta.All)
|
||||||
if options.Cursor == "" && (options.Direction == storj.Before || options.Direction == storj.Backward) {
|
|
||||||
endBefore = "\x7f\x7f\x7f\x7f\x7f\x7f\x7f"
|
|
||||||
}
|
|
||||||
|
|
||||||
items, more, err := objects.List(ctx, options.Prefix, startAfter, endBefore, options.Recursive, options.Limit, meta.All)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return storj.ObjectList{}, err
|
return storj.ObjectList{}, err
|
||||||
}
|
}
|
||||||
|
@ -294,8 +294,6 @@ func TestListObjectsEmpty(t *testing.T) {
|
|||||||
|
|
||||||
// TODO for now we are supporting only storj.After
|
// TODO for now we are supporting only storj.After
|
||||||
for _, direction := range []storj.ListDirection{
|
for _, direction := range []storj.ListDirection{
|
||||||
// storj.Before,
|
|
||||||
// storj.Backward,
|
|
||||||
// storj.Forward,
|
// storj.Forward,
|
||||||
storj.After,
|
storj.After,
|
||||||
} {
|
} {
|
||||||
@ -334,311 +332,80 @@ func TestListObjects(t *testing.T) {
|
|||||||
result []string
|
result []string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
options: options("", "", storj.After, 0),
|
options: options("", "", 0),
|
||||||
result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"},
|
result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"},
|
||||||
}, {
|
}, {
|
||||||
options: options("", "`", storj.After, 0),
|
options: options("", "`", 0),
|
||||||
result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"},
|
result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"},
|
||||||
}, {
|
}, {
|
||||||
options: options("", "b", storj.After, 0),
|
options: options("", "b", 0),
|
||||||
result: []string{"b/", "bb", "c"},
|
result: []string{"b/", "bb", "c"},
|
||||||
}, {
|
}, {
|
||||||
options: options("", "c", storj.After, 0),
|
options: options("", "c", 0),
|
||||||
result: []string{},
|
result: []string{},
|
||||||
}, {
|
}, {
|
||||||
options: options("", "ca", storj.After, 0),
|
options: options("", "ca", 0),
|
||||||
result: []string{},
|
result: []string{},
|
||||||
}, {
|
}, {
|
||||||
options: options("", "", storj.After, 1),
|
options: options("", "", 1),
|
||||||
more: true,
|
more: true,
|
||||||
result: []string{"a"},
|
result: []string{"a"},
|
||||||
}, {
|
}, {
|
||||||
options: options("", "`", storj.After, 1),
|
options: options("", "`", 1),
|
||||||
more: true,
|
more: true,
|
||||||
result: []string{"a"},
|
result: []string{"a"},
|
||||||
}, {
|
}, {
|
||||||
options: options("", "aa", storj.After, 1),
|
options: options("", "aa", 1),
|
||||||
more: true,
|
more: true,
|
||||||
result: []string{"b"},
|
result: []string{"b"},
|
||||||
}, {
|
}, {
|
||||||
options: options("", "c", storj.After, 1),
|
options: options("", "c", 1),
|
||||||
result: []string{},
|
result: []string{},
|
||||||
}, {
|
}, {
|
||||||
options: options("", "ca", storj.After, 1),
|
options: options("", "ca", 1),
|
||||||
result: []string{},
|
result: []string{},
|
||||||
}, {
|
}, {
|
||||||
options: options("", "", storj.After, 2),
|
options: options("", "", 2),
|
||||||
more: true,
|
more: true,
|
||||||
result: []string{"a", "a/"},
|
result: []string{"a", "a/"},
|
||||||
}, {
|
}, {
|
||||||
options: options("", "`", storj.After, 2),
|
options: options("", "`", 2),
|
||||||
more: true,
|
more: true,
|
||||||
result: []string{"a", "a/"},
|
result: []string{"a", "a/"},
|
||||||
}, {
|
}, {
|
||||||
options: options("", "aa", storj.After, 2),
|
options: options("", "aa", 2),
|
||||||
more: true,
|
more: true,
|
||||||
result: []string{"b", "b/"},
|
result: []string{"b", "b/"},
|
||||||
}, {
|
}, {
|
||||||
options: options("", "bb", storj.After, 2),
|
options: options("", "bb", 2),
|
||||||
result: []string{"c"},
|
result: []string{"c"},
|
||||||
}, {
|
}, {
|
||||||
options: options("", "c", storj.After, 2),
|
options: options("", "c", 2),
|
||||||
result: []string{},
|
result: []string{},
|
||||||
}, {
|
}, {
|
||||||
options: options("", "ca", storj.After, 2),
|
options: options("", "ca", 2),
|
||||||
result: []string{},
|
result: []string{},
|
||||||
}, {
|
}, {
|
||||||
options: optionsRecursive("", "", storj.After, 0),
|
options: optionsRecursive("", "", 0),
|
||||||
result: []string{"a", "a/xa", "a/xaa", "a/xb", "a/xbb", "a/xc", "aa", "b", "b/ya", "b/yaa", "b/yb", "b/ybb", "b/yc", "bb", "c"},
|
result: []string{"a", "a/xa", "a/xaa", "a/xb", "a/xbb", "a/xc", "aa", "b", "b/ya", "b/yaa", "b/yb", "b/ybb", "b/yc", "bb", "c"},
|
||||||
}, {
|
}, {
|
||||||
options: options("a", "", storj.After, 0),
|
options: options("a", "", 0),
|
||||||
result: []string{"xa", "xaa", "xb", "xbb", "xc"},
|
result: []string{"xa", "xaa", "xb", "xbb", "xc"},
|
||||||
}, {
|
}, {
|
||||||
options: options("a/", "", storj.After, 0),
|
options: options("a/", "", 0),
|
||||||
result: []string{"xa", "xaa", "xb", "xbb", "xc"},
|
result: []string{"xa", "xaa", "xb", "xbb", "xc"},
|
||||||
}, {
|
}, {
|
||||||
options: options("a/", "xb", storj.After, 0),
|
options: options("a/", "xb", 0),
|
||||||
result: []string{"xbb", "xc"},
|
result: []string{"xbb", "xc"},
|
||||||
}, {
|
}, {
|
||||||
options: optionsRecursive("", "a/xbb", storj.After, 5),
|
options: optionsRecursive("", "a/xbb", 5),
|
||||||
more: true,
|
more: true,
|
||||||
result: []string{"a/xc", "aa", "b", "b/ya", "b/yaa"},
|
result: []string{"a/xc", "aa", "b", "b/ya", "b/yaa"},
|
||||||
}, {
|
}, {
|
||||||
options: options("a/", "xaa", storj.After, 2),
|
options: options("a/", "xaa", 2),
|
||||||
more: true,
|
more: true,
|
||||||
result: []string{"xb", "xbb"},
|
result: []string{"xb", "xbb"},
|
||||||
},
|
},
|
||||||
// TODO commented until we will decide if we will support direction for object listing
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// options: options("", "", storj.Forward, 0),
|
|
||||||
// result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "`", storj.Forward, 0),
|
|
||||||
// result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "b", storj.Forward, 0),
|
|
||||||
// result: []string{"b", "b/", "bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "c", storj.Forward, 0),
|
|
||||||
// result: []string{"c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "ca", storj.Forward, 0),
|
|
||||||
// result: []string{},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "", storj.Forward, 1),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"a"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "`", storj.Forward, 1),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"a"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "aa", storj.Forward, 1),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"aa"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "c", storj.Forward, 1),
|
|
||||||
// result: []string{"c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "ca", storj.Forward, 1),
|
|
||||||
// result: []string{},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "", storj.Forward, 2),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"a", "a/"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "`", storj.Forward, 2),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"a", "a/"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "aa", storj.Forward, 2),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"aa", "b"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "bb", storj.Forward, 2),
|
|
||||||
// result: []string{"bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "c", storj.Forward, 2),
|
|
||||||
// result: []string{"c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "ca", storj.Forward, 2),
|
|
||||||
// result: []string{},
|
|
||||||
// }, {
|
|
||||||
// options: optionsRecursive("", "", storj.Forward, 0),
|
|
||||||
// result: []string{"a", "a/xa", "a/xaa", "a/xb", "a/xbb", "a/xc", "aa", "b", "b/ya", "b/yaa", "b/yb", "b/ybb", "b/yc", "bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("a", "", storj.Forward, 0),
|
|
||||||
// result: []string{"xa", "xaa", "xb", "xbb", "xc"},
|
|
||||||
// }, {
|
|
||||||
// options: options("a/", "", storj.Forward, 0),
|
|
||||||
// result: []string{"xa", "xaa", "xb", "xbb", "xc"},
|
|
||||||
// }, {
|
|
||||||
// options: options("a/", "xb", storj.Forward, 0),
|
|
||||||
// result: []string{"xb", "xbb", "xc"},
|
|
||||||
// }, {
|
|
||||||
// options: optionsRecursive("", "a/xbb", storj.Forward, 5),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"a/xbb", "a/xc", "aa", "b", "b/ya"},
|
|
||||||
// }, {
|
|
||||||
// options: options("a/", "xaa", storj.Forward, 2),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"xaa", "xb"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "", storj.Backward, 0),
|
|
||||||
// result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "`", storj.Backward, 0),
|
|
||||||
// result: []string{},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "b", storj.Backward, 0),
|
|
||||||
// result: []string{"a", "a/", "aa", "b"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "c", storj.Backward, 0),
|
|
||||||
// result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "ca", storj.Backward, 0),
|
|
||||||
// result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "", storj.Backward, 1),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "`", storj.Backward, 1),
|
|
||||||
// result: []string{},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "aa", storj.Backward, 1),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"aa"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "c", storj.Backward, 1),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "ca", storj.Backward, 1),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "", storj.Backward, 2),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "`", storj.Backward, 2),
|
|
||||||
// result: []string{},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "a/", storj.Backward, 2),
|
|
||||||
// result: []string{"a"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "bb", storj.Backward, 2),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"b/", "bb"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "c", storj.Backward, 2),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "ca", storj.Backward, 2),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: optionsRecursive("", "", storj.Backward, 0),
|
|
||||||
// result: []string{"a", "a/xa", "a/xaa", "a/xb", "a/xbb", "a/xc", "aa", "b", "b/ya", "b/yaa", "b/yb", "b/ybb", "b/yc", "bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("a", "", storj.Backward, 0),
|
|
||||||
// result: []string{"xa", "xaa", "xb", "xbb", "xc"},
|
|
||||||
// }, {
|
|
||||||
// options: options("a/", "", storj.Backward, 0),
|
|
||||||
// result: []string{"xa", "xaa", "xb", "xbb", "xc"},
|
|
||||||
// }, {
|
|
||||||
// options: options("a/", "xb", storj.Backward, 0),
|
|
||||||
// result: []string{"xa", "xaa", "xb"},
|
|
||||||
// }, {
|
|
||||||
// options: optionsRecursive("", "b/yaa", storj.Backward, 5),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"a/xc", "aa", "b", "b/ya", "b/yaa"},
|
|
||||||
// }, {
|
|
||||||
// options: options("a/", "xbb", storj.Backward, 2),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"xb", "xbb"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "", storj.Before, 0),
|
|
||||||
// result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "`", storj.Before, 0),
|
|
||||||
// result: []string{},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "a", storj.Before, 0),
|
|
||||||
// result: []string{},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "b", storj.Before, 0),
|
|
||||||
// result: []string{"a", "a/", "aa"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "c", storj.Before, 0),
|
|
||||||
// result: []string{"a", "a/", "aa", "b", "b/", "bb"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "ca", storj.Before, 0),
|
|
||||||
// result: []string{"a", "a/", "aa", "b", "b/", "bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "", storj.Before, 1),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "`", storj.Before, 1),
|
|
||||||
// result: []string{},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "a/", storj.Before, 1),
|
|
||||||
// result: []string{"a"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "c", storj.Before, 1),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"bb"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "ca", storj.Before, 1),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "", storj.Before, 2),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "`", storj.Before, 2),
|
|
||||||
// result: []string{},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "a/", storj.Before, 2),
|
|
||||||
// result: []string{"a"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "bb", storj.Before, 2),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"b", "b/"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "c", storj.Before, 2),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"b/", "bb"},
|
|
||||||
// }, {
|
|
||||||
// options: options("", "ca", storj.Before, 2),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: optionsRecursive("", "", storj.Before, 0),
|
|
||||||
// result: []string{"a", "a/xa", "a/xaa", "a/xb", "a/xbb", "a/xc", "aa", "b", "b/ya", "b/yaa", "b/yb", "b/ybb", "b/yc", "bb", "c"},
|
|
||||||
// }, {
|
|
||||||
// options: options("a", "", storj.Before, 0),
|
|
||||||
// result: []string{"xa", "xaa", "xb", "xbb", "xc"},
|
|
||||||
// }, {
|
|
||||||
// options: options("a/", "", storj.Before, 0),
|
|
||||||
// result: []string{"xa", "xaa", "xb", "xbb", "xc"},
|
|
||||||
// }, {
|
|
||||||
// options: options("a/", "xb", storj.Before, 0),
|
|
||||||
// result: []string{"xa", "xaa"},
|
|
||||||
// }, {
|
|
||||||
// options: optionsRecursive("", "b/yaa", storj.Before, 5),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"a/xbb", "a/xc", "aa", "b", "b/ya"},
|
|
||||||
// }, {
|
|
||||||
// options: options("a/", "xbb", storj.Before, 2),
|
|
||||||
// more: true,
|
|
||||||
// result: []string{"xaa", "xb"},
|
|
||||||
// },
|
|
||||||
} {
|
} {
|
||||||
errTag := fmt.Sprintf("%d. %+v", i, tt)
|
errTag := fmt.Sprintf("%d. %+v", i, tt)
|
||||||
|
|
||||||
@ -655,20 +422,20 @@ func TestListObjects(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
func options(prefix, cursor string, direction storj.ListDirection, limit int) storj.ListOptions {
|
func options(prefix, cursor string, limit int) storj.ListOptions {
|
||||||
return storj.ListOptions{
|
return storj.ListOptions{
|
||||||
Prefix: prefix,
|
Prefix: prefix,
|
||||||
Cursor: cursor,
|
Cursor: cursor,
|
||||||
Direction: direction,
|
Direction: storj.After,
|
||||||
Limit: limit,
|
Limit: limit,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func optionsRecursive(prefix, cursor string, direction storj.ListDirection, limit int) storj.ListOptions {
|
func optionsRecursive(prefix, cursor string, limit int) storj.ListOptions {
|
||||||
return storj.ListOptions{
|
return storj.ListOptions{
|
||||||
Prefix: prefix,
|
Prefix: prefix,
|
||||||
Cursor: cursor,
|
Cursor: cursor,
|
||||||
Direction: direction,
|
Direction: storj.After,
|
||||||
Limit: limit,
|
Limit: limit,
|
||||||
Recursive: true,
|
Recursive: true,
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,8 @@ func (o *prefixedObjStore) Delete(ctx context.Context, path storj.Path) (err err
|
|||||||
return o.store.Delete(ctx, storj.JoinPaths(o.prefix, path))
|
return o.store.Delete(ctx, storj.JoinPaths(o.prefix, path))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *prefixedObjStore) List(ctx context.Context, prefix, startAfter, endBefore storj.Path, recursive bool, limit int, metaFlags uint32) (items []objects.ListItem, more bool, err error) {
|
func (o *prefixedObjStore) List(ctx context.Context, prefix, startAfter storj.Path, recursive bool, limit int, metaFlags uint32) (items []objects.ListItem, more bool, err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
return o.store.List(ctx, storj.JoinPaths(o.prefix, prefix), startAfter, endBefore, recursive, limit, metaFlags)
|
return o.store.List(ctx, storj.JoinPaths(o.prefix, prefix), startAfter, recursive, limit, metaFlags)
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ type Store interface {
|
|||||||
Get(ctx context.Context, path storj.Path) (rr ranger.Ranger, meta Meta, err error)
|
Get(ctx context.Context, path storj.Path) (rr ranger.Ranger, meta Meta, err error)
|
||||||
Put(ctx context.Context, path storj.Path, data io.Reader, metadata pb.SerializableMeta, expiration time.Time) (meta Meta, err error)
|
Put(ctx context.Context, path storj.Path, data io.Reader, metadata pb.SerializableMeta, expiration time.Time) (meta Meta, err error)
|
||||||
Delete(ctx context.Context, path storj.Path) (err error)
|
Delete(ctx context.Context, path storj.Path) (err error)
|
||||||
List(ctx context.Context, prefix, startAfter, endBefore storj.Path, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error)
|
List(ctx context.Context, prefix, startAfter storj.Path, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type objStore struct {
|
type objStore struct {
|
||||||
@ -123,11 +123,11 @@ func (o *objStore) Delete(ctx context.Context, path storj.Path) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *objStore) List(ctx context.Context, prefix, startAfter, endBefore storj.Path, recursive bool, limit int, metaFlags uint32) (
|
func (o *objStore) List(ctx context.Context, prefix, startAfter storj.Path, recursive bool, limit int, metaFlags uint32) (
|
||||||
items []ListItem, more bool, err error) {
|
items []ListItem, more bool, err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
strItems, more, err := o.store.List(ctx, prefix, startAfter, endBefore, o.pathCipher, recursive, limit, metaFlags)
|
strItems, more, err := o.store.List(ctx, prefix, startAfter, o.pathCipher, recursive, limit, metaFlags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ type Store interface {
|
|||||||
Get(ctx context.Context, path storj.Path, pathCipher storj.CipherSuite) (ranger.Ranger, Meta, error)
|
Get(ctx context.Context, path storj.Path, pathCipher storj.CipherSuite) (ranger.Ranger, Meta, error)
|
||||||
Put(ctx context.Context, path storj.Path, pathCipher storj.CipherSuite, data io.Reader, metadata []byte, expiration time.Time) (Meta, error)
|
Put(ctx context.Context, path storj.Path, pathCipher storj.CipherSuite, data io.Reader, metadata []byte, expiration time.Time) (Meta, error)
|
||||||
Delete(ctx context.Context, path storj.Path, pathCipher storj.CipherSuite) error
|
Delete(ctx context.Context, path storj.Path, pathCipher storj.CipherSuite) error
|
||||||
List(ctx context.Context, prefix, startAfter, endBefore storj.Path, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error)
|
List(ctx context.Context, prefix, startAfter storj.Path, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type shimStore struct {
|
type shimStore struct {
|
||||||
@ -66,8 +66,8 @@ func (s *shimStore) Delete(ctx context.Context, path storj.Path, pathCipher stor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// List parses the passed in path and dispatches to the typed store.
|
// List parses the passed in path and dispatches to the typed store.
|
||||||
func (s *shimStore) List(ctx context.Context, prefix storj.Path, startAfter storj.Path, endBefore storj.Path, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error) {
|
func (s *shimStore) List(ctx context.Context, prefix storj.Path, startAfter storj.Path, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
return s.store.List(ctx, ParsePath(prefix), startAfter, endBefore, pathCipher, recursive, limit, metaFlags)
|
return s.store.List(ctx, ParsePath(prefix), startAfter, pathCipher, recursive, limit, metaFlags)
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ type typedStore interface {
|
|||||||
Get(ctx context.Context, path Path, pathCipher storj.CipherSuite) (ranger.Ranger, Meta, error)
|
Get(ctx context.Context, path Path, pathCipher storj.CipherSuite) (ranger.Ranger, Meta, error)
|
||||||
Put(ctx context.Context, path Path, pathCipher storj.CipherSuite, data io.Reader, metadata []byte, expiration time.Time) (Meta, error)
|
Put(ctx context.Context, path Path, pathCipher storj.CipherSuite, data io.Reader, metadata []byte, expiration time.Time) (Meta, error)
|
||||||
Delete(ctx context.Context, path Path, pathCipher storj.CipherSuite) error
|
Delete(ctx context.Context, path Path, pathCipher storj.CipherSuite) error
|
||||||
List(ctx context.Context, prefix Path, startAfter, endBefore string, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error)
|
List(ctx context.Context, prefix Path, startAfter string, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// streamStore is a store for streams. It implements typedStore as part of an ongoing migration
|
// streamStore is a store for streams. It implements typedStore as part of an ongoing migration
|
||||||
@ -582,7 +582,7 @@ func pathForKey(raw string) paths.Unencrypted {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// List all the paths inside l/, stripping off the l/ prefix
|
// List all the paths inside l/, stripping off the l/ prefix
|
||||||
func (s *streamStore) List(ctx context.Context, prefix Path, startAfter, endBefore string, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error) {
|
func (s *streamStore) List(ctx context.Context, prefix Path, startAfter string, pathCipher storj.CipherSuite, recursive bool, limit int, metaFlags uint32) (items []ListItem, more bool, err error) {
|
||||||
defer mon.Task()(&ctx)(&err)
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
// TODO use flags with listing
|
// TODO use flags with listing
|
||||||
@ -611,9 +611,9 @@ func (s *streamStore) List(ctx context.Context, prefix Path, startAfter, endBefo
|
|||||||
encPrefix = paths.NewEncrypted(encPrefix.Raw()[:lastSlashIdx])
|
encPrefix = paths.NewEncrypted(encPrefix.Raw()[:lastSlashIdx])
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have to encrypt startAfter and endBefore but only if they don't contain a bucket.
|
// We have to encrypt startAfter but only if it doesn't contain a bucket.
|
||||||
// They contain a bucket if and only if the prefix has no bucket. This is why they are raw
|
// It contains a bucket if and only if the prefix has no bucket. This is why it is a raw
|
||||||
// strings instead of a typed string: it's either a bucket or an unencrypted path component
|
// string instead of a typed string: it's either a bucket or an unencrypted path component
|
||||||
// and that isn't known at compile time.
|
// and that isn't known at compile time.
|
||||||
needsEncryption := prefix.Bucket() != ""
|
needsEncryption := prefix.Bucket() != ""
|
||||||
if needsEncryption {
|
if needsEncryption {
|
||||||
|
@ -132,7 +132,7 @@ func TestStreamsInterruptedDelete(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Ensure the item shows when we list
|
// Ensure the item shows when we list
|
||||||
listItems, _, err := streamStore.List(ctx, bucketName, "", "", storj.EncNull, true, 10, meta.None)
|
listItems, _, err := streamStore.List(ctx, bucketName, "", storj.EncNull, true, 10, meta.None)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, len(listItems) == 1)
|
require.True(t, len(listItems) == 1)
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ func TestStreamsInterruptedDelete(t *testing.T) {
|
|||||||
|
|
||||||
// It should *still* show when we list, as we've only deleted one
|
// It should *still* show when we list, as we've only deleted one
|
||||||
// segment
|
// segment
|
||||||
listItems, _, err = streamStore.List(ctx, bucketName, "", "", storj.EncNull, true, 10, meta.None)
|
listItems, _, err = streamStore.List(ctx, bucketName, "", storj.EncNull, true, 10, meta.None)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, len(listItems) == 1)
|
require.True(t, len(listItems) == 1)
|
||||||
|
|
||||||
@ -168,7 +168,7 @@ func TestStreamsInterruptedDelete(t *testing.T) {
|
|||||||
_ = streamStore.Delete(ctx, fullPath, storj.EncNull)
|
_ = streamStore.Delete(ctx, fullPath, storj.EncNull)
|
||||||
|
|
||||||
// Now it should have 0 list items
|
// Now it should have 0 list items
|
||||||
listItems, _, err = streamStore.List(ctx, bucketName, "", "", storj.EncNull, true, 10, meta.None)
|
listItems, _, err = streamStore.List(ctx, bucketName, "", storj.EncNull, true, 10, meta.None)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, len(listItems) == 0)
|
require.True(t, len(listItems) == 0)
|
||||||
})
|
})
|
||||||
@ -203,39 +203,39 @@ func TestStreamStoreList(t *testing.T) {
|
|||||||
prefix := bucketName
|
prefix := bucketName
|
||||||
|
|
||||||
// should list all
|
// should list all
|
||||||
items, more, err := streamStore.List(ctx, prefix, "", "", storj.EncNull, true, 10, meta.None)
|
items, more, err := streamStore.List(ctx, prefix, "", storj.EncNull, true, 10, meta.None)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.False(t, more)
|
require.False(t, more)
|
||||||
require.Equal(t, len(objects), len(items))
|
require.Equal(t, len(objects), len(items))
|
||||||
|
|
||||||
// should list first two and more = true
|
// should list first two and more = true
|
||||||
items, more, err = streamStore.List(ctx, prefix, "", "", storj.EncNull, true, 2, meta.None)
|
items, more, err = streamStore.List(ctx, prefix, "", storj.EncNull, true, 2, meta.None)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, more)
|
require.True(t, more)
|
||||||
require.Equal(t, 2, len(items))
|
require.Equal(t, 2, len(items))
|
||||||
|
|
||||||
// should list only prefixes
|
// should list only prefixes
|
||||||
items, more, err = streamStore.List(ctx, prefix, "", "", storj.EncNull, false, 10, meta.None)
|
items, more, err = streamStore.List(ctx, prefix, "", storj.EncNull, false, 10, meta.None)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.False(t, more)
|
require.False(t, more)
|
||||||
require.Equal(t, 2, len(items))
|
require.Equal(t, 2, len(items))
|
||||||
|
|
||||||
// should list only BBBB bucket
|
// should list only BBBB bucket
|
||||||
prefix = storj.JoinPaths(bucketName, "bbbb")
|
prefix = storj.JoinPaths(bucketName, "bbbb")
|
||||||
items, more, err = streamStore.List(ctx, prefix, "", "", storj.EncNull, false, 10, meta.None)
|
items, more, err = streamStore.List(ctx, prefix, "", storj.EncNull, false, 10, meta.None)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.False(t, more)
|
require.False(t, more)
|
||||||
require.Equal(t, 3, len(items))
|
require.Equal(t, 3, len(items))
|
||||||
|
|
||||||
// should list only BBBB bucket after afile
|
// should list only BBBB bucket after afile
|
||||||
items, more, err = streamStore.List(ctx, prefix, "afile1", "", storj.EncNull, false, 10, meta.None)
|
items, more, err = streamStore.List(ctx, prefix, "afile1", storj.EncNull, false, 10, meta.None)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.False(t, more)
|
require.False(t, more)
|
||||||
require.Equal(t, 2, len(items))
|
require.Equal(t, 2, len(items))
|
||||||
|
|
||||||
// should list nothing
|
// should list nothing
|
||||||
prefix = storj.JoinPaths(bucketName, "cccc")
|
prefix = storj.JoinPaths(bucketName, "cccc")
|
||||||
items, more, err = streamStore.List(ctx, prefix, "", "", storj.EncNull, true, 10, meta.None)
|
items, more, err = streamStore.List(ctx, prefix, "", storj.EncNull, true, 10, meta.None)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.False(t, more)
|
require.False(t, more)
|
||||||
require.Equal(t, 0, len(items))
|
require.Equal(t, 0, len(items))
|
||||||
|
Loading…
Reference in New Issue
Block a user