Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: common/recordio/reader.go

Issue 1834123002: common/recordio: Add zero-copy buffer split. (Closed) Base URL: https://github.com/luci/luci-go@symlink-clean
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | common/recordio/reader_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package recordio 5 package recordio
6 6
7 import ( 7 import (
8 "bytes"
8 "encoding/binary" 9 "encoding/binary"
9 "fmt" 10 "fmt"
10 "io" 11 "io"
11 ) 12 )
12 13
13 // ErrFrameTooLarge is an error that is returned if a frame that is larger than 14 // ErrFrameTooLarge is an error that is returned if a frame that is larger than
14 // the maximum allowed size (not including the frame header) is read. 15 // the maximum allowed size (not including the frame header) is read.
15 var ErrFrameTooLarge = fmt.Errorf("frame: frame size exceeds maximum") 16 var ErrFrameTooLarge = fmt.Errorf("frame: frame size exceeds maximum")
16 17
17 // Reader reads individual frames from a frame-formatted input Reader. 18 // Reader reads individual frames from a frame-formatted input Reader.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 type simpleByteReader struct { 96 type simpleByteReader struct {
96 io.Reader 97 io.Reader
97 98
98 buf [1]byte 99 buf [1]byte
99 } 100 }
100 101
101 func (r *simpleByteReader) ReadByte() (byte, error) { 102 func (r *simpleByteReader) ReadByte() (byte, error) {
102 _, err := r.Read(r.buf[:]) 103 _, err := r.Read(r.buf[:])
103 return r.buf[0], err 104 return r.buf[0], err
104 } 105 }
106
107 // Split splits the supplied buffer into its component records.
108 //
109 // This method implements zero-copy segmentation, so the individual records are
110 // slices of the original data set.
111 func Split(data []byte) (records [][]byte, err error) {
112 br := bytes.NewReader(data)
113
114 for br.Len() > 0 {
115 var size uint64
116 size, err = binary.ReadUvarint(br)
117 if err != nil {
118 return
119 }
120 if size > uint64(br.Len()) {
121 err = ErrFrameTooLarge
122 return
123 }
124
125 // Pull out the record from the original byte stream without cop ying.
126 // Casting size to an integer is safe at this point, since we ha ve asserted
127 // that it is less than the remaining length in the buffer, whic h is an int.
128 offset := len(data) - br.Len()
129 records = append(records, data[offset:offset+int(size)])
130
131 if _, err := br.Seek(int64(size), 1); err != nil {
132 // Our measurements should protect us from this being an invalid seek.
133 panic(err)
134 }
135 }
136 return records, nil
137 }
OLDNEW
« no previous file with comments | « no previous file | common/recordio/reader_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698