Codebase list golang-github-cznic-ql / 9827cc7
Imported Upstream version 1.0.2 Dmitry Smirnov 8 years ago
41 changed file(s) with 18740 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
1212 // powerful than SQL (whichever specification SQL is considered to be).
1313 //
1414 // Change list
15 //
16 // 2016-03-23: Release v1.0.2 vendors github.com/cznic/exp/lldb and
17 // github.com/camlistore/go4/lock.
1518 //
1619 // 2016-03-17: Release v1.0.1 adjusts for latest goyacc. Parser error messages
1720 // are improved and changed, but their exact form is not considered a API
1818 "sync"
1919 "time"
2020
21 "github.com/camlistore/go4/lock"
22 "github.com/cznic/exp/lldb"
2321 "github.com/cznic/mathutil"
22 "github.com/cznic/ql/vendored/github.com/camlistore/go4/lock"
23 "github.com/cznic/ql/vendored/github.com/cznic/exp/lldb"
2424 )
2525
2626 const (
0 # This is the official list of go4 authors for copyright purposes.
1 # This is distinct from the CONTRIBUTORS file, which is the list of
2 # people who have contributed, even if they don't own the copyright on
3 # their work.
4
5 Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
6 Daniel Theophanes <kardianos@gmail.com>
7 Google
0 Apache License
1 Version 2.0, January 2004
2 http://www.apache.org/licenses/
3
4 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
5
6 1. Definitions.
7
8 "License" shall mean the terms and conditions for use, reproduction,
9 and distribution as defined by Sections 1 through 9 of this document.
10
11 "Licensor" shall mean the copyright owner or entity authorized by
12 the copyright owner that is granting the License.
13
14 "Legal Entity" shall mean the union of the acting entity and all
15 other entities that control, are controlled by, or are under common
16 control with that entity. For the purposes of this definition,
17 "control" means (i) the power, direct or indirect, to cause the
18 direction or management of such entity, whether by contract or
19 otherwise, or (ii) ownership of fifty percent (50%) or more of the
20 outstanding shares, or (iii) beneficial ownership of such entity.
21
22 "You" (or "Your") shall mean an individual or Legal Entity
23 exercising permissions granted by this License.
24
25 "Source" form shall mean the preferred form for making modifications,
26 including but not limited to software source code, documentation
27 source, and configuration files.
28
29 "Object" form shall mean any form resulting from mechanical
30 transformation or translation of a Source form, including but
31 not limited to compiled object code, generated documentation,
32 and conversions to other media types.
33
34 "Work" shall mean the work of authorship, whether in Source or
35 Object form, made available under the License, as indicated by a
36 copyright notice that is included in or attached to the work
37 (an example is provided in the Appendix below).
38
39 "Derivative Works" shall mean any work, whether in Source or Object
40 form, that is based on (or derived from) the Work and for which the
41 editorial revisions, annotations, elaborations, or other modifications
42 represent, as a whole, an original work of authorship. For the purposes
43 of this License, Derivative Works shall not include works that remain
44 separable from, or merely link (or bind by name) to the interfaces of,
45 the Work and Derivative Works thereof.
46
47 "Contribution" shall mean any work of authorship, including
48 the original version of the Work and any modifications or additions
49 to that Work or Derivative Works thereof, that is intentionally
50 submitted to Licensor for inclusion in the Work by the copyright owner
51 or by an individual or Legal Entity authorized to submit on behalf of
52 the copyright owner. For the purposes of this definition, "submitted"
53 means any form of electronic, verbal, or written communication sent
54 to the Licensor or its representatives, including but not limited to
55 communication on electronic mailing lists, source code control systems,
56 and issue tracking systems that are managed by, or on behalf of, the
57 Licensor for the purpose of discussing and improving the Work, but
58 excluding communication that is conspicuously marked or otherwise
59 designated in writing by the copyright owner as "Not a Contribution."
60
61 "Contributor" shall mean Licensor and any individual or Legal Entity
62 on behalf of whom a Contribution has been received by Licensor and
63 subsequently incorporated within the Work.
64
65 2. Grant of Copyright License. Subject to the terms and conditions of
66 this License, each Contributor hereby grants to You a perpetual,
67 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
68 copyright license to reproduce, prepare Derivative Works of,
69 publicly display, publicly perform, sublicense, and distribute the
70 Work and such Derivative Works in Source or Object form.
71
72 3. Grant of Patent License. Subject to the terms and conditions of
73 this License, each Contributor hereby grants to You a perpetual,
74 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
75 (except as stated in this section) patent license to make, have made,
76 use, offer to sell, sell, import, and otherwise transfer the Work,
77 where such license applies only to those patent claims licensable
78 by such Contributor that are necessarily infringed by their
79 Contribution(s) alone or by combination of their Contribution(s)
80 with the Work to which such Contribution(s) was submitted. If You
81 institute patent litigation against any entity (including a
82 cross-claim or counterclaim in a lawsuit) alleging that the Work
83 or a Contribution incorporated within the Work constitutes direct
84 or contributory patent infringement, then any patent licenses
85 granted to You under this License for that Work shall terminate
86 as of the date such litigation is filed.
87
88 4. Redistribution. You may reproduce and distribute copies of the
89 Work or Derivative Works thereof in any medium, with or without
90 modifications, and in Source or Object form, provided that You
91 meet the following conditions:
92
93 (a) You must give any other recipients of the Work or
94 Derivative Works a copy of this License; and
95
96 (b) You must cause any modified files to carry prominent notices
97 stating that You changed the files; and
98
99 (c) You must retain, in the Source form of any Derivative Works
100 that You distribute, all copyright, patent, trademark, and
101 attribution notices from the Source form of the Work,
102 excluding those notices that do not pertain to any part of
103 the Derivative Works; and
104
105 (d) If the Work includes a "NOTICE" text file as part of its
106 distribution, then any Derivative Works that You distribute must
107 include a readable copy of the attribution notices contained
108 within such NOTICE file, excluding those notices that do not
109 pertain to any part of the Derivative Works, in at least one
110 of the following places: within a NOTICE text file distributed
111 as part of the Derivative Works; within the Source form or
112 documentation, if provided along with the Derivative Works; or,
113 within a display generated by the Derivative Works, if and
114 wherever such third-party notices normally appear. The contents
115 of the NOTICE file are for informational purposes only and
116 do not modify the License. You may add Your own attribution
117 notices within Derivative Works that You distribute, alongside
118 or as an addendum to the NOTICE text from the Work, provided
119 that such additional attribution notices cannot be construed
120 as modifying the License.
121
122 You may add Your own copyright statement to Your modifications and
123 may provide additional or different license terms and conditions
124 for use, reproduction, or distribution of Your modifications, or
125 for any such Derivative Works as a whole, provided Your use,
126 reproduction, and distribution of the Work otherwise complies with
127 the conditions stated in this License.
128
129 5. Submission of Contributions. Unless You explicitly state otherwise,
130 any Contribution intentionally submitted for inclusion in the Work
131 by You to the Licensor shall be under the terms and conditions of
132 this License, without any additional terms or conditions.
133 Notwithstanding the above, nothing herein shall supersede or modify
134 the terms of any separate license agreement you may have executed
135 with Licensor regarding such Contributions.
136
137 6. Trademarks. This License does not grant permission to use the trade
138 names, trademarks, service marks, or product names of the Licensor,
139 except as required for reasonable and customary use in describing the
140 origin of the Work and reproducing the content of the NOTICE file.
141
142 7. Disclaimer of Warranty. Unless required by applicable law or
143 agreed to in writing, Licensor provides the Work (and each
144 Contributor provides its Contributions) on an "AS IS" BASIS,
145 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
146 implied, including, without limitation, any warranties or conditions
147 of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
148 PARTICULAR PURPOSE. You are solely responsible for determining the
149 appropriateness of using or redistributing the Work and assume any
150 risks associated with Your exercise of permissions under this License.
151
152 8. Limitation of Liability. In no event and under no legal theory,
153 whether in tort (including negligence), contract, or otherwise,
154 unless required by applicable law (such as deliberate and grossly
155 negligent acts) or agreed to in writing, shall any Contributor be
156 liable to You for damages, including any direct, indirect, special,
157 incidental, or consequential damages of any character arising as a
158 result of this License or out of the use or inability to use the
159 Work (including but not limited to damages for loss of goodwill,
160 work stoppage, computer failure or malfunction, or any and all
161 other commercial damages or losses), even if such Contributor
162 has been advised of the possibility of such damages.
163
164 9. Accepting Warranty or Additional Liability. While redistributing
165 the Work or Derivative Works thereof, You may choose to offer,
166 and charge a fee for, acceptance of support, warranty, indemnity,
167 or other liability obligations and/or rights consistent with this
168 License. However, in accepting such obligations, You may act only
169 on Your own behalf and on Your sole responsibility, not on behalf
170 of any other Contributor, and only if You agree to indemnify,
171 defend, and hold each Contributor harmless for any liability
172 incurred by, or claims asserted against, such Contributor by reason
173 of your accepting any such warranty or additional liability.
174
175 END OF TERMS AND CONDITIONS
176
177 APPENDIX: How to apply the Apache License to your work.
178
179 To apply the Apache License to your work, attach the following
180 boilerplate notice, with the fields enclosed by brackets "{}"
181 replaced with your own identifying information. (Don't include
182 the brackets!) The text should be enclosed in the appropriate
183 comment syntax for the file format. We also recommend that a
184 file or class name and description of purpose be included on the
185 same "printed page" as the copyright notice for easier
186 identification within third-party archives.
187
188 Copyright {yyyy} {name of copyright owner}
189
190 Licensed under the Apache License, Version 2.0 (the "License");
191 you may not use this file except in compliance with the License.
192 You may obtain a copy of the License at
193
194 http://www.apache.org/licenses/LICENSE-2.0
195
196 Unless required by applicable law or agreed to in writing, software
197 distributed under the License is distributed on an "AS IS" BASIS,
198 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
199 See the License for the specific language governing permissions and
200 limitations under the License.
201
0 # go4
1
2 [![travis badge](https://travis-ci.org/camlistore/go4.svg?branch=master)](https://travis-ci.org/camlistore/go4 "Travis CI")
3
4 [go4.org](http://go4.org) is a collection of packages for
5 Go programmers.
6
7 They started out living in [Camlistore](https://camlistore.org)'s repo
8 and elsewhere but they have nothing to do with Camlistore, so we're
9 moving them here.
10
11 ## Details
12
13 * **single repo**. go4 is a single repo. That means things can be
14 changed and rearranged globally atomically with ease and
15 confidence.
16
17 * **no backwards compatibility**. go4 makes no backwards compatibility
18 promises. If you want to use go4, vendor it. And next time you
19 update your vendor tree, update to the latest API if things in go4
20 changed. The plan is to eventually provide tools to make this
21 easier.
22
23 * **forward progress** because we have no backwards compatibility,
24 it's always okay to change things to make things better. That also
25 means the bar for contributions is lower. We don't have to get the
26 API 100% correct in the first commit.
27
28 * **code review** contributions must be code-reviewed. We're trying
29 out Gerrithub, to see if we can find a mix of Github Pull Requests
30 and Gerrit that works well for many people. We'll see.
31
32 * **CLA compliant** contributors must agree to the Google CLA (the
33 same as Go itself). This ensures we can move things into Go as
34 necessary in the future. It also makes lawyers at various
35 companies happy. The CLA is **not** a copyright *assignment*; you
36 retain the copyright on your work. The CLA just says that your
37 work is open source and you have permission to open source it. See
38 https://golang.org/doc/contribute.html#tmp_6
39
40 * **docs, tests, portability** all code should be documented in the
41 normal Go style, have tests, and be portable to different
42 operating systems and architectures. We'll try to get builders in
43 place to help run the tests on different OS/arches. For now we
44 have Travis at least.
45
46 ## Contributing
47
48 To add code to go4, send a pull request or push a change to Gerrithub.
49
50 We assume you already have your $GOPATH set and the go4 code cloned at
51 $GOPATH/src/go4.org. For example:
52
53 * git clone https://review.gerrithub.io/camlistore/go4 $GOPATH/src/go4.org
54
55 ### To push a code review to Gerrithub directly:
56
57 * Sign in to [http://gerrithub.io](http://gerrithub.io "Gerrithub") with your Github account.
58
59 Install the git hook that adds the magic "Change-Id" line to your commit messages:
60
61 * curl -o $GOPATH/src/go4.org/.git/hooks/commit-msg https://camlistore.googlesource.com/camlistore/+/master/misc/commit-msg.githook
62
63 * make changes
64
65 * commit (the unit of code review is a single commit identified by the Change-ID, **NOT** a series of commits on a branch)
66
67 * git push ssh://$YOUR_GITHUB_USERNAME@review.gerrithub.io:29418/camlistore/go4 HEAD:refs/for/master
68
69 ### Using Github Pull Requests
70
71 * send a pull request with a single commit
72
73 * create a Gerrithub code review at https://review.gerrithub.io/plugins/github-plugin/static/pullrequests.html, selecting the pull request you just created.
74
75 ### Problems contributing?
76
77 * Please file an issue or contact the [Camlistore mailing list](https://groups.google.com/forum/#!forum/camlistore) for any problems with the above.
78
79 See [https://review.gerrithub.io/Documentation/user-upload.html](https://review.gerrithub.io/Documentation/user-upload.html) for more generic documentation.
80
81 (TODO: more docs on Gerrit, integrate git-codereview, etc.)
82
0 /*
1 Copyright 2013 The Go Authors
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 */
15
16 // Package lock is a file locking library.
17 package lock
18
19 import (
20 "encoding/json"
21 "fmt"
22 "io"
23 "os"
24 "path/filepath"
25 "sync"
26 )
27
28 // Lock locks the given file, creating the file if necessary. If the
29 // file already exists, it must have zero size or an error is returned.
30 // The lock is an exclusive lock (a write lock), but locked files
31 // should neither be read from nor written to. Such files should have
32 // zero size and only exist to co-ordinate ownership across processes.
33 //
34 // A nil Closer is returned if an error occurred. Otherwise, close that
35 // Closer to release the lock.
36 //
37 // On Linux, FreeBSD and OSX, a lock has the same semantics as fcntl(2)'s
38 // advisory locks. In particular, closing any other file descriptor for the
39 // same file will release the lock prematurely.
40 //
41 // Attempting to lock a file that is already locked by the current process
42 // has undefined behavior.
43 //
44 // On other operating systems, lock will fallback to using the presence and
45 // content of a file named name + '.lock' to implement locking behavior.
46 func Lock(name string) (io.Closer, error) {
47 abs, err := filepath.Abs(name)
48 if err != nil {
49 return nil, err
50 }
51 lockmu.Lock()
52 defer lockmu.Unlock()
53 if locked[abs] {
54 return nil, fmt.Errorf("file %q already locked", abs)
55 }
56
57 c, err := lockFn(abs)
58 if err != nil {
59 return nil, fmt.Errorf("cannot acquire lock: %v", err)
60 }
61 locked[abs] = true
62 return c, nil
63 }
64
65 var lockFn = lockPortable
66
67 // lockPortable is a portable version not using fcntl. Doesn't handle crashes as gracefully,
68 // since it can leave stale lock files.
69 func lockPortable(name string) (io.Closer, error) {
70 fi, err := os.Stat(name)
71 if err == nil && fi.Size() > 0 {
72 st := portableLockStatus(name)
73 switch st {
74 case statusLocked:
75 return nil, fmt.Errorf("file %q already locked", name)
76 case statusStale:
77 os.Remove(name)
78 case statusInvalid:
79 return nil, fmt.Errorf("can't Lock file %q: has invalid contents", name)
80 }
81 }
82 f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_EXCL, 0666)
83 if err != nil {
84 return nil, fmt.Errorf("failed to create lock file %s %v", name, err)
85 }
86 if err := json.NewEncoder(f).Encode(&pidLockMeta{OwnerPID: os.Getpid()}); err != nil {
87 return nil, fmt.Errorf("cannot write owner pid: %v", err)
88 }
89 return &unlocker{
90 f: f,
91 abs: name,
92 portable: true,
93 }, nil
94 }
95
96 type lockStatus int
97
98 const (
99 statusInvalid lockStatus = iota
100 statusLocked
101 statusUnlocked
102 statusStale
103 )
104
105 type pidLockMeta struct {
106 OwnerPID int
107 }
108
109 func portableLockStatus(path string) lockStatus {
110 f, err := os.Open(path)
111 if err != nil {
112 return statusUnlocked
113 }
114 defer f.Close()
115 var meta pidLockMeta
116 if json.NewDecoder(f).Decode(&meta) != nil {
117 return statusInvalid
118 }
119 if meta.OwnerPID == 0 {
120 return statusInvalid
121 }
122 p, err := os.FindProcess(meta.OwnerPID)
123 if err != nil {
124 // e.g. on Windows
125 return statusStale
126 }
127 // On unix, os.FindProcess always is true, so we have to send
128 // it a signal to see if it's alive.
129 if signalZero != nil {
130 if p.Signal(signalZero) != nil {
131 return statusStale
132 }
133 }
134 return statusLocked
135 }
136
137 var signalZero os.Signal // nil or set by lock_sigzero.go
138
139 var (
140 lockmu sync.Mutex
141 locked = map[string]bool{} // abs path -> true
142 )
143
144 type unlocker struct {
145 portable bool
146 f *os.File
147 abs string
148 // once guards the close method call.
149 once sync.Once
150 // err holds the error returned by Close.
151 err error
152 }
153
154 func (u *unlocker) Close() error {
155 u.once.Do(u.close)
156 return u.err
157 }
158
159 func (u *unlocker) close() {
160 lockmu.Lock()
161 defer lockmu.Unlock()
162 delete(locked, u.abs)
163
164 if u.portable {
165 // In the portable lock implementation, it's
166 // important to close before removing because
167 // Windows won't allow us to remove an open
168 // file.
169 if err := u.f.Close(); err != nil {
170 u.err = err
171 }
172 if err := os.Remove(u.abs); err != nil {
173 // Note that if both Close and Remove fail,
174 // we care more about the latter than the former
175 // so we'll return that error.
176 u.err = err
177 }
178 return
179 }
180 // In other implementatioons, it's nice for us to clean up.
181 // If we do do this, though, it needs to be before the
182 // u.f.Close below.
183 os.Remove(u.abs)
184 u.err = u.f.Close()
185 }
0 // +build appengine
1
2 /*
3 Copyright 2013 The Go Authors
4
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 */
17
18 package lock
19
20 import (
21 "errors"
22 "io"
23 )
24
25 func init() {
26 lockFn = lockAppEngine
27 }
28
29 func lockAppEngine(name string) (io.Closer, error) {
30 return nil, errors.New("Lock not available on App Engine")
31 }
0 // +build darwin,amd64
1 // +build !appengine
2
3 /*
4 Copyright 2013 The Go Authors
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 */
18
19 package lock
20
21 import (
22 "fmt"
23 "io"
24 "os"
25 "syscall"
26 "unsafe"
27 )
28
29 func init() {
30 lockFn = lockFcntl
31 }
32
33 func lockFcntl(name string) (io.Closer, error) {
34 fi, err := os.Stat(name)
35 if err == nil && fi.Size() > 0 {
36 return nil, fmt.Errorf("can't Lock file %q: has non-zero size", name)
37 }
38
39 f, err := os.Create(name)
40 if err != nil {
41 return nil, fmt.Errorf("Lock Create of %s failed: %v", name, err)
42 }
43
44 // This type matches C's "struct flock" defined in /usr/include/sys/fcntl.h.
45 // TODO: move this into the standard syscall package.
46 k := struct {
47 Start uint64 // sizeof(off_t): 8
48 Len uint64 // sizeof(off_t): 8
49 Pid uint32 // sizeof(pid_t): 4
50 Type uint16 // sizeof(short): 2
51 Whence uint16 // sizeof(short): 2
52 }{
53 Type: syscall.F_WRLCK,
54 Whence: uint16(os.SEEK_SET),
55 Start: 0,
56 Len: 0, // 0 means to lock the entire file.
57 Pid: uint32(os.Getpid()),
58 }
59
60 _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_SETLK), uintptr(unsafe.Pointer(&k)))
61 if errno != 0 {
62 f.Close()
63 return nil, errno
64 }
65 return &unlocker{f: f, abs: name}, nil
66 }
0 /*
1 Copyright 2013 The Go Authors
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 */
15
16 package lock
17
18 import (
19 "fmt"
20 "io"
21 "os"
22 "syscall"
23 "unsafe"
24 )
25
26 func init() {
27 lockFn = lockFcntl
28 }
29
30 func lockFcntl(name string) (io.Closer, error) {
31 fi, err := os.Stat(name)
32 if err == nil && fi.Size() > 0 {
33 return nil, fmt.Errorf("can't Lock file %q: has non-zero size", name)
34 }
35
36 f, err := os.Create(name)
37 if err != nil {
38 return nil, err
39 }
40
41 // This type matches C's "struct flock" defined in /usr/include/fcntl.h.
42 // TODO: move this into the standard syscall package.
43 k := struct {
44 Start int64 /* off_t starting offset */
45 Len int64 /* off_t len = 0 means until end of file */
46 Pid int32 /* pid_t lock owner */
47 Type int16 /* short lock type: read/write, etc. */
48 Whence int16 /* short type of l_start */
49 Sysid int32 /* int remote system id or zero for local */
50 }{
51 Start: 0,
52 Len: 0, // 0 means to lock the entire file.
53 Pid: int32(os.Getpid()),
54 Type: syscall.F_WRLCK,
55 Whence: int16(os.SEEK_SET),
56 Sysid: 0,
57 }
58
59 _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_SETLK), uintptr(unsafe.Pointer(&k)))
60 if errno != 0 {
61 f.Close()
62 return nil, errno
63 }
64 return &unlocker{f: f, abs: name}, nil
65 }
0 // +build linux,amd64
1 // +build !appengine
2
3 /*
4 Copyright 2013 The Go Authors
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 */
18
19 package lock
20
21 import (
22 "fmt"
23 "io"
24 "os"
25 "syscall"
26 "unsafe"
27 )
28
29 func init() {
30 lockFn = lockFcntl
31 }
32
33 func lockFcntl(name string) (io.Closer, error) {
34 fi, err := os.Stat(name)
35 if err == nil && fi.Size() > 0 {
36 return nil, fmt.Errorf("can't Lock file %q: has non-zero size", name)
37 }
38
39 f, err := os.Create(name)
40 if err != nil {
41 return nil, err
42 }
43
44 // This type matches C's "struct flock" defined in /usr/include/bits/fcntl.h.
45 // TODO: move this into the standard syscall package.
46 k := struct {
47 Type uint32
48 Whence uint32
49 Start uint64
50 Len uint64
51 Pid uint32
52 }{
53 Type: syscall.F_WRLCK,
54 Whence: uint32(os.SEEK_SET),
55 Start: 0,
56 Len: 0, // 0 means to lock the entire file.
57 Pid: uint32(os.Getpid()),
58 }
59
60 _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_SETLK), uintptr(unsafe.Pointer(&k)))
61 if errno != 0 {
62 f.Close()
63 return nil, errno
64 }
65 return &unlocker{f: f, abs: name}, nil
66 }
0 // +build linux,arm
1 // +build !appengine
2
3 /*
4 Copyright 2013 The Go Authors
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 */
18
19 package lock
20
21 import (
22 "fmt"
23 "io"
24 "os"
25 "syscall"
26 "unsafe"
27 )
28
29 func init() {
30 lockFn = lockFcntl
31 }
32
33 func lockFcntl(name string) (io.Closer, error) {
34 fi, err := os.Stat(name)
35 if err == nil && fi.Size() > 0 {
36 return nil, fmt.Errorf("can't Lock file %q: has non-zero size", name)
37 }
38
39 f, err := os.Create(name)
40 if err != nil {
41 return nil, err
42 }
43
44 // This type matches C's "struct flock" defined in /usr/include/bits/fcntl.h.
45 // TODO: move this into the standard syscall package.
46 k := struct {
47 Type uint16
48 Whence uint16
49 Start uint32
50 Len uint32
51 Pid uint32
52 }{
53 Type: syscall.F_WRLCK,
54 Whence: uint16(os.SEEK_SET),
55 Start: 0,
56 Len: 0, // 0 means to lock the entire file.
57 Pid: uint32(os.Getpid()),
58 }
59
60 const F_SETLK = 6 // actual value. syscall package is wrong: golang.org/issue/7059
61 _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(F_SETLK), uintptr(unsafe.Pointer(&k)))
62 if errno != 0 {
63 f.Close()
64 return nil, errno
65 }
66 return &unlocker{f: f, abs: name}, nil
67 }
0 /*
1 Copyright 2013 The Go Authors
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 */
15
16 package lock
17
18 import (
19 "fmt"
20 "io"
21 "os"
22 )
23
24 func init() {
25 lockFn = lockPlan9
26 }
27
28 func lockPlan9(name string) (io.Closer, error) {
29 fi, err := os.Stat(name)
30 if err == nil && fi.Size() > 0 {
31 return nil, fmt.Errorf("can't Lock file %q: has non-zero size", name)
32 }
33
34 f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE, os.ModeExclusive|0644)
35 if err != nil {
36 return nil, fmt.Errorf("Lock Create of %s failed: %v", name, err)
37 }
38
39 return &unlocker{f: f, abs: name}, nil
40 }
0 // +build !appengine
1 // +build linux darwin freebsd openbsd netbsd dragonfly
2
3 /*
4 Copyright 2013 The Go Authors
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 */
18
19 package lock
20
21 import "syscall"
22
23 func init() {
24 signalZero = syscall.Signal(0)
25 }
0 /*
1 Copyright 2013 The Go Authors
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 */
15
16 package lock
17
18 import (
19 "bufio"
20 "errors"
21 "fmt"
22 "io"
23 "io/ioutil"
24 "os"
25 "os/exec"
26 "path/filepath"
27 "strconv"
28 "testing"
29 )
30
31 func TestLock(t *testing.T) {
32 testLock(t, false)
33 }
34
35 func TestLockPortable(t *testing.T) {
36 testLock(t, true)
37 }
38
39 func TestLockInChild(t *testing.T) {
40 f := os.Getenv("TEST_LOCK_FILE")
41 if f == "" {
42 // not child
43 return
44 }
45 lock := Lock
46 if v, _ := strconv.ParseBool(os.Getenv("TEST_LOCK_PORTABLE")); v {
47 lock = lockPortable
48 }
49
50 var lk io.Closer
51 for scan := bufio.NewScanner(os.Stdin); scan.Scan(); {
52 var err error
53 switch scan.Text() {
54 case "lock":
55 lk, err = lock(f)
56 case "unlock":
57 err = lk.Close()
58 lk = nil
59 case "exit":
60 // Simulate a crash, or at least not unlocking the lock.
61 os.Exit(0)
62 default:
63 err = fmt.Errorf("unexpected child command %q", scan.Text())
64 }
65 if err != nil {
66 fmt.Println(err)
67 } else {
68 fmt.Println("")
69 }
70 }
71 }
72
73 func testLock(t *testing.T, portable bool) {
74 lock := Lock
75 if portable {
76 lock = lockPortable
77 }
78 t.Logf("test lock, portable %v", portable)
79
80 td, err := ioutil.TempDir("", "")
81 if err != nil {
82 t.Fatal(err)
83 }
84 defer os.RemoveAll(td)
85
86 path := filepath.Join(td, "foo.lock")
87
88 proc := newChildProc(t, path, portable)
89 defer proc.kill()
90
91 t.Logf("First lock in child")
92 if err := proc.do("lock"); err != nil {
93 t.Fatalf("first lock in child process: %v", err)
94 }
95
96 t.Logf("Crash child")
97 if err := proc.do("exit"); err != nil {
98 t.Fatalf("crash in child process: %v", err)
99 }
100
101 proc = newChildProc(t, path, portable)
102 defer proc.kill()
103
104 t.Logf("Locking+unlocking in child...")
105 if err := proc.do("lock"); err != nil {
106 t.Fatalf("lock in child process after crashing child: %v", err)
107 }
108 if err := proc.do("unlock"); err != nil {
109 t.Fatalf("lock in child process after crashing child: %v", err)
110 }
111
112 t.Logf("Locking in parent...")
113 lk1, err := lock(path)
114 if err != nil {
115 t.Fatal(err)
116 }
117
118 t.Logf("Again in parent...")
119 _, err = lock(path)
120 if err == nil {
121 t.Fatal("expected second lock to fail")
122 }
123
124 t.Logf("Locking in child...")
125 if err := proc.do("lock"); err == nil {
126 t.Fatalf("expected lock in child process to fail")
127 }
128
129 t.Logf("Unlocking lock in parent")
130 if err := lk1.Close(); err != nil {
131 t.Fatal(err)
132 }
133
134 t.Logf("Trying lock again in child...")
135 if err := proc.do("lock"); err != nil {
136 t.Fatal(err)
137 }
138 if err := proc.do("unlock"); err != nil {
139 t.Fatal(err)
140 }
141
142 lk3, err := lock(path)
143 if err != nil {
144 t.Fatal(err)
145 }
146 lk3.Close()
147 }
148
149 type childLockCmd struct {
150 op string
151 reply chan<- error
152 }
153
154 type childProc struct {
155 proc *os.Process
156 c chan childLockCmd
157 }
158
159 func (c *childProc) kill() {
160 c.proc.Kill()
161 }
162
163 func (c *childProc) do(op string) error {
164 reply := make(chan error)
165 c.c <- childLockCmd{
166 op: op,
167 reply: reply,
168 }
169 return <-reply
170 }
171
172 func newChildProc(t *testing.T, path string, portable bool) *childProc {
173 cmd := exec.Command(os.Args[0], "-test.run=LockInChild$")
174 cmd.Env = []string{"TEST_LOCK_FILE=" + path}
175 toChild, err := cmd.StdinPipe()
176 if err != nil {
177 t.Fatalf("cannot make pipe: %v", err)
178 }
179 fromChild, err := cmd.StdoutPipe()
180 if err != nil {
181 t.Fatalf("cannot make pipe: %v", err)
182 }
183 cmd.Stderr = os.Stderr
184 if portable {
185 cmd.Env = append(cmd.Env, "TEST_LOCK_PORTABLE=1")
186 }
187 if err := cmd.Start(); err != nil {
188 t.Fatalf("cannot start child: %v", err)
189 }
190 cmdChan := make(chan childLockCmd)
191 go func() {
192 defer fromChild.Close()
193 defer toChild.Close()
194 inScan := bufio.NewScanner(fromChild)
195 for c := range cmdChan {
196 fmt.Fprintln(toChild, c.op)
197 ok := inScan.Scan()
198 if c.op == "exit" {
199 if ok {
200 c.reply <- errors.New("child did not exit")
201 } else {
202 cmd.Wait()
203 c.reply <- nil
204 }
205 break
206 }
207 if !ok {
208 panic("child exited early")
209 }
210 if errText := inScan.Text(); errText != "" {
211 c.reply <- errors.New(errText)
212 } else {
213 c.reply <- nil
214 }
215 }
216 }()
217 return &childProc{
218 c: cmdChan,
219 proc: cmd.Process,
220 }
221 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 // Two Phase Commit & Structural ACID
5
6 package lldb
7
8 import (
9 "bufio"
10 "encoding/binary"
11 "fmt"
12 "io"
13 "os"
14
15 "github.com/cznic/fileutil"
16 "github.com/cznic/mathutil"
17 )
18
19 var _ Filer = &ACIDFiler0{} // Ensure ACIDFiler0 is a Filer
20
21 type acidWrite struct {
22 b []byte
23 off int64
24 }
25
26 type acidWriter0 ACIDFiler0
27
28 func (a *acidWriter0) WriteAt(b []byte, off int64) (n int, err error) {
29 f := (*ACIDFiler0)(a)
30 if f.bwal == nil { // new epoch
31 f.data = f.data[:0]
32 f.bwal = bufio.NewWriter(f.wal)
33 if err = a.writePacket([]interface{}{wpt00Header, walTypeACIDFiler0, ""}); err != nil {
34 return
35 }
36 }
37
38 if err = a.writePacket([]interface{}{wpt00WriteData, b, off}); err != nil {
39 return
40 }
41
42 f.data = append(f.data, acidWrite{b, off})
43 return len(b), nil
44 }
45
46 func (a *acidWriter0) writePacket(items []interface{}) (err error) {
47 f := (*ACIDFiler0)(a)
48 b, err := EncodeScalars(items...)
49 if err != nil {
50 return
51 }
52
53 var b4 [4]byte
54 binary.BigEndian.PutUint32(b4[:], uint32(len(b)))
55 if _, err = f.bwal.Write(b4[:]); err != nil {
56 return
57 }
58
59 if _, err = f.bwal.Write(b); err != nil {
60 return
61 }
62
63 if m := (4 + len(b)) % 16; m != 0 {
64 var pad [15]byte
65 _, err = f.bwal.Write(pad[:16-m])
66 }
67 return
68 }
69
70 // WAL Packet Tags
71 const (
72 wpt00Header = iota
73 wpt00WriteData
74 wpt00Checkpoint
75 )
76
77 const (
78 walTypeACIDFiler0 = iota
79 )
80
81 // ACIDFiler0 is a very simple, synchronous implementation of 2PC. It uses a
82 // single write ahead log file to provide the structural atomicity
83 // (BeginUpdate/EndUpdate/Rollback) and durability (DB can be recovered from
84 // WAL if a crash occurred).
85 //
86 // ACIDFiler0 is a Filer.
87 //
88 // NOTE: Durable synchronous 2PC involves three fsyncs in this implementation
89 // (WAL, DB, zero truncated WAL). Where possible, it's recommended to collect
90 // transactions for, say one second before performing the two phase commit as
91 // the typical performance for rotational hard disks is about few tens of
92 // fsyncs per second atmost. For an example of such collective transaction
93 // approach please see the colecting FSM STT in Dbm's documentation[1].
94 //
95 // [1]: http://godoc.org/github.com/cznic/exp/dbm
96 type ACIDFiler0 struct {
97 *RollbackFiler
98 wal *os.File
99 bwal *bufio.Writer
100 data []acidWrite
101 testHook bool // keeps WAL untruncated (once)
102 peakWal int64 // tracks WAL maximum used size
103 peakBitFilerPages int // track maximum transaction memory
104 }
105
106 // NewACIDFiler0 returns a newly created ACIDFiler0 with WAL in wal.
107 //
108 // If the WAL is zero sized then a previous clean shutdown of db is taken for
109 // granted and no recovery procedure is taken.
110 //
111 // If the WAL is of non zero size then it is checked for having a
112 // commited/fully finished transaction not yet been reflected in db. If such
113 // transaction exists it's committed to db. If the recovery process finishes
114 // successfully, the WAL is truncated to zero size and fsync'ed prior to return
115 // from NewACIDFiler0.
116 func NewACIDFiler(db Filer, wal *os.File) (r *ACIDFiler0, err error) {
117 fi, err := wal.Stat()
118 if err != nil {
119 return
120 }
121
122 r = &ACIDFiler0{wal: wal}
123
124 if fi.Size() != 0 {
125 if err = r.recoverDb(db); err != nil {
126 return
127 }
128 }
129
130 acidWriter := (*acidWriter0)(r)
131
132 if r.RollbackFiler, err = NewRollbackFiler(
133 db,
134 func(sz int64) (err error) {
135 // Checkpoint
136 if err = acidWriter.writePacket([]interface{}{wpt00Checkpoint, sz}); err != nil {
137 return
138 }
139
140 if err = r.bwal.Flush(); err != nil {
141 return
142 }
143
144 r.bwal = nil
145
146 if err = r.wal.Sync(); err != nil {
147 return
148 }
149
150 wfi, err := r.wal.Stat()
151 switch err != nil {
152 case true:
153 // unexpected, but ignored
154 case false:
155 r.peakWal = mathutil.MaxInt64(wfi.Size(), r.peakWal)
156 }
157
158 // Phase 1 commit complete
159
160 for _, v := range r.data {
161 if _, err := db.WriteAt(v.b, v.off); err != nil {
162 return err
163 }
164 }
165
166 if err = db.Truncate(sz); err != nil {
167 return
168 }
169
170 if err = db.Sync(); err != nil {
171 return
172 }
173
174 // Phase 2 commit complete
175
176 if !r.testHook {
177 if err = r.wal.Truncate(0); err != nil {
178 return
179 }
180
181 if _, err = r.wal.Seek(0, 0); err != nil {
182 return
183 }
184 }
185
186 r.testHook = false
187 return r.wal.Sync()
188
189 },
190 acidWriter,
191 ); err != nil {
192 return
193 }
194
195 return r, nil
196 }
197
198 // PeakWALSize reports the maximum size WAL has ever used.
199 func (a ACIDFiler0) PeakWALSize() int64 {
200 return a.peakWal
201 }
202
203 func (a *ACIDFiler0) readPacket(f *bufio.Reader) (items []interface{}, err error) {
204 var b4 [4]byte
205 n, err := io.ReadAtLeast(f, b4[:], 4)
206 if n != 4 {
207 return
208 }
209
210 ln := int(binary.BigEndian.Uint32(b4[:]))
211 m := (4 + ln) % 16
212 padd := (16 - m) % 16
213 b := make([]byte, ln+padd)
214 if n, err = io.ReadAtLeast(f, b, len(b)); n != len(b) {
215 return
216 }
217
218 return DecodeScalars(b[:ln])
219 }
220
221 func (a *ACIDFiler0) recoverDb(db Filer) (err error) {
222 fi, err := a.wal.Stat()
223 if err != nil {
224 return &ErrILSEQ{Type: ErrInvalidWAL, Name: a.wal.Name(), More: err}
225 }
226
227 if sz := fi.Size(); sz%16 != 0 {
228 return &ErrILSEQ{Type: ErrFileSize, Name: a.wal.Name(), Arg: sz}
229 }
230
231 f := bufio.NewReader(a.wal)
232 items, err := a.readPacket(f)
233 if err != nil {
234 return
235 }
236
237 if len(items) != 3 || items[0] != int64(wpt00Header) || items[1] != int64(walTypeACIDFiler0) {
238 return &ErrILSEQ{Type: ErrInvalidWAL, Name: a.wal.Name(), More: fmt.Sprintf("invalid packet items %#v", items)}
239 }
240
241 tr := NewBTree(nil)
242
243 for {
244 items, err = a.readPacket(f)
245 if err != nil {
246 return
247 }
248
249 if len(items) < 2 {
250 return &ErrILSEQ{Type: ErrInvalidWAL, Name: a.wal.Name(), More: fmt.Sprintf("too few packet items %#v", items)}
251 }
252
253 switch items[0] {
254 case int64(wpt00WriteData):
255 if len(items) != 3 {
256 return &ErrILSEQ{Type: ErrInvalidWAL, Name: a.wal.Name(), More: fmt.Sprintf("invalid data packet items %#v", items)}
257 }
258
259 b, off := items[1].([]byte), items[2].(int64)
260 var key [8]byte
261 binary.BigEndian.PutUint64(key[:], uint64(off))
262 if err = tr.Set(key[:], b); err != nil {
263 return
264 }
265 case int64(wpt00Checkpoint):
266 var b1 [1]byte
267 if n, err := f.Read(b1[:]); n != 0 || err == nil {
268 return &ErrILSEQ{Type: ErrInvalidWAL, Name: a.wal.Name(), More: fmt.Sprintf("checkpoint n %d, err %v", n, err)}
269 }
270
271 if len(items) != 2 {
272 return &ErrILSEQ{Type: ErrInvalidWAL, Name: a.wal.Name(), More: fmt.Sprintf("checkpoint packet invalid items %#v", items)}
273 }
274
275 sz := items[1].(int64)
276 enum, err := tr.seekFirst()
277 if err != nil {
278 return err
279 }
280
281 for {
282 k, v, err := enum.current()
283 if err != nil {
284 if fileutil.IsEOF(err) {
285 break
286 }
287
288 return err
289 }
290
291 if _, err = db.WriteAt(v, int64(binary.BigEndian.Uint64(k))); err != nil {
292 return err
293 }
294
295 if err = enum.next(); err != nil {
296 if fileutil.IsEOF(err) {
297 break
298 }
299
300 return err
301 }
302 }
303
304 if err = db.Truncate(sz); err != nil {
305 return err
306 }
307
308 if err = db.Sync(); err != nil {
309 return err
310 }
311
312 // Recovery complete
313
314 if err = a.wal.Truncate(0); err != nil {
315 return err
316 }
317
318 return a.wal.Sync()
319 default:
320 return &ErrILSEQ{Type: ErrInvalidWAL, Name: a.wal.Name(), More: fmt.Sprintf("packet tag %v", items[0])}
321 }
322 }
323 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 /*
5
6 Anatomy of a WAL file
7
8 WAL file
9 A sequence of packets
10
11 WAL packet, parts in slice notation
12 [0:4], 4 bytes: N uint32 // network byte order
13 [4:4+N], N bytes: payload []byte // gb encoded scalars
14
15 Packets, including the 4 byte 'size' prefix, MUST BE padded to size == 0 (mod
16 16). The values of the padding bytes MUST BE zero.
17
18 Encoded scalars first item is a packet type number (packet tag). The meaning of
19 any other item(s) of the payload depends on the packet tag.
20
21 Packet definitions
22
23 {wpt00Header int, typ int, s string}
24 typ: Must be zero (ACIDFiler0 file).
25 s: Any comment string, empty string is okay.
26
27 This packet must be present only once - as the first packet of
28 a WAL file.
29
30 {wpt00WriteData int, b []byte, off int64}
31 Write data (WriteAt(b, off)).
32
33 {wpt00Checkpoint int, sz int64}
34 Checkpoint (Truncate(sz)).
35
36 This packet must be present only once - as the last packet of
37 a WAL file.
38
39 */
40
41 package lldb
42
43 //TODO optimize bitfiler/wal/2pc data above final size
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 // Two Phase Commit & Structural ACID
5
6 package lldb
7
8 import (
9 "bytes"
10 "encoding/binary"
11 "io/ioutil"
12 "math/rand"
13 "os"
14 "testing"
15
16 "github.com/cznic/mathutil"
17 )
18
19 var _ Filer = &truncFiler{}
20
21 type truncFiler struct {
22 f Filer
23 fake *MemFiler
24 totalWritten int // Including silently dropped
25 realWritten int
26 limit int // -1: unlimited, n: silently stop writing after limit bytes
27 }
28
29 func NewTruncFiler(f Filer, limit int) *truncFiler {
30 return &truncFiler{f: f, fake: NewMemFiler(), limit: limit}
31 }
32
33 func (f *truncFiler) BeginUpdate() error { panic("internal error") }
34 func (f *truncFiler) Close() error { return f.f.Close() }
35 func (f *truncFiler) EndUpdate() error { panic("internal error") }
36 func (f *truncFiler) Name() string { return f.f.Name() }
37 func (f *truncFiler) PunchHole(off, sz int64) error { panic("internal error") }
38 func (f *truncFiler) ReadAt(b []byte, off int64) (int, error) { return f.fake.ReadAt(b, off) }
39 func (f *truncFiler) Rollback() error { panic("internal error") }
40 func (f *truncFiler) Size() (int64, error) { return f.fake.Size() }
41 func (f *truncFiler) Sync() error { return f.f.Sync() }
42
43 func (f *truncFiler) Truncate(sz int64) error {
44 f.fake.Truncate(sz)
45 return f.f.Truncate(sz)
46 }
47
48 func (f *truncFiler) WriteAt(b []byte, off int64) (n int, err error) {
49 rq := len(b)
50 n = f.totalWritten
51 if lim := f.limit; lim >= 0 && n+rq > lim {
52 over := n + rq - lim
53 rq -= over
54 rq = mathutil.Max(rq, 0)
55 }
56
57 if n, err = f.fake.WriteAt(b, off); err != nil {
58 return
59 }
60
61 f.totalWritten += n
62 if rq != 0 {
63 n, err := f.f.WriteAt(b[:rq], off)
64 if err != nil {
65 return n, err
66 }
67 f.realWritten += n
68 }
69 return
70 }
71
72 // Verify memory BTrees don't have maxRq limits.
73 func TestACID0MemBTreeCaps(t *testing.T) {
74 rng := rand.New(rand.NewSource(42))
75 tr := NewBTree(nil)
76 b := make([]byte, 2*maxRq)
77 for i := range b {
78 b[i] = byte(rng.Int())
79 }
80
81 if err := tr.Set(nil, b); err != nil {
82 t.Fatal(len(b), err)
83 }
84
85 g, err := tr.Get(nil, nil)
86 if err != nil {
87 t.Fatal(err)
88 }
89
90 if !bytes.Equal(g, b) {
91 t.Fatal("data mismatach")
92 }
93 }
94
95 func TestACIDFiler0(t *testing.T) {
96 const SZ = 1 << 17
97
98 // Phase 1: Create a DB, fill with it with data.
99
100 wal, err := ioutil.TempFile("", "test-acidfiler0-wal-")
101 if err != nil {
102 t.Fatal(err)
103 }
104
105 if !*oKeep {
106 defer os.Remove(wal.Name())
107 }
108
109 db, err := ioutil.TempFile("", "test-acidfiler0-db-")
110 if err != nil {
111 t.Fatal(err)
112 }
113
114 dbName := db.Name()
115 if !*oKeep {
116 defer os.Remove(db.Name())
117 }
118
119 realFiler := NewSimpleFileFiler(db)
120 truncFiler := NewTruncFiler(realFiler, -1)
121 acidFiler, err := NewACIDFiler(truncFiler, wal)
122 if err != nil {
123 t.Error(err)
124 return
125 }
126
127 if err = acidFiler.BeginUpdate(); err != nil {
128 t.Error(err)
129 return
130 }
131
132 a, err := NewAllocator(acidFiler, &Options{})
133 if err != nil {
134 t.Error(err)
135 return
136 }
137
138 a.Compress = true
139
140 tr, h, err := CreateBTree(a, nil)
141 if h != 1 || err != nil {
142 t.Error(h, err)
143 return
144 }
145
146 rng := rand.New(rand.NewSource(42))
147 var key, val [8]byte
148 ref := map[int64]int64{}
149
150 for {
151 sz, err := acidFiler.Size()
152 if err != nil {
153 t.Error(err)
154 return
155 }
156
157 if sz > SZ {
158 break
159 }
160
161 k, v := rng.Int63(), rng.Int63()
162 ref[k] = v
163 binary.BigEndian.PutUint64(key[:], uint64(k))
164 binary.BigEndian.PutUint64(val[:], uint64(v))
165 if err := tr.Set(key[:], val[:]); err != nil {
166 t.Error(err)
167 return
168 }
169 }
170
171 acidFiler.testHook = true // keep WAL
172
173 if err := acidFiler.EndUpdate(); err != nil {
174 t.Error(err)
175 return
176 }
177
178 if err := acidFiler.Close(); err != nil {
179 t.Error(err)
180 return
181 }
182
183 if err := wal.Sync(); err != nil {
184 t.Error(err)
185 return
186 }
187
188 if _, err = wal.Seek(0, 0); err != nil {
189 t.Error(err)
190 return
191 }
192
193 // Phase 2: Reopen and verify structure and data.
194 db, err = os.OpenFile(dbName, os.O_RDWR, 0666)
195 if err != nil {
196 t.Error(err)
197 return
198 }
199
200 filer := NewSimpleFileFiler(db)
201 a, err = NewAllocator(filer, &Options{})
202 if err != nil {
203 t.Error(err)
204 return
205 }
206
207 if err = a.Verify(NewMemFiler(), nil, nil); err != nil {
208 t.Error(err)
209 return
210 }
211
212 tr, err = OpenBTree(a, nil, 1)
213 for k, v := range ref {
214 binary.BigEndian.PutUint64(key[:], uint64(k))
215 binary.BigEndian.PutUint64(val[:], uint64(v))
216 var b []byte
217 b, err = tr.Get(b, key[:])
218 if err != nil || b == nil || !bytes.Equal(b, val[:]) {
219 t.Error(err, b, val[:])
220 return
221 }
222 }
223
224 okImage, err := ioutil.ReadFile(dbName)
225 if err != nil {
226 t.Error(err)
227 return
228 }
229
230 // Phase 3: Simulate a crash
231 sz, err := filer.Size()
232 if err != nil {
233 t.Error(err)
234 return
235 }
236
237 sz /= 2
238 if err := db.Truncate(sz); err != nil {
239 t.Error(err)
240 return
241 }
242
243 z := make([]byte, sz/3)
244 n, err := db.WriteAt(z, sz/3)
245 if n != len(z) {
246 t.Error(n, err)
247 return
248 }
249
250 if err := db.Sync(); err != nil {
251 t.Error(err)
252 return
253 }
254
255 // Phase 4: Open the corrupted DB
256 filer = NewSimpleFileFiler(db)
257 acidFiler, err = NewACIDFiler(filer, wal)
258 if err != nil {
259 t.Error(err)
260 return
261 }
262
263 if err = acidFiler.Sync(); err != nil {
264 t.Error(err)
265 return
266 }
267
268 if err = acidFiler.Close(); err != nil {
269 t.Error(err)
270 return
271 }
272
273 // Phase 5: Verify DB was recovered.
274 newImage, err := ioutil.ReadFile(dbName)
275 if err != nil {
276 t.Error(err)
277 return
278 }
279
280 if !bytes.Equal(okImage, newImage) {
281 t.Error(err)
282 return
283 }
284 }
0 # This file lists authors for copyright purposes. This file is distinct from
1 # the CONTRIBUTORS files. See the latter for an explanation.
2 #
3 # Names should be added to this file as:
4 # Name or Organization <email address>
5 #
6 # The email address is not required for organizations.
7 #
8 # Please keep the list sorted.
9
10 Jan Mercl <0xjnml@gmail.com>
0 # This file lists people who contributed code to this repository. The AUTHORS
1 # file lists the copyright holders; this file lists people.
2 #
3 # Names should be added to this file like so:
4 # Name <email address>
5 #
6 # Please keep the list sorted.
7
8 Jan Mercl <0xjnml@gmail.com>
9 Patrick Mézard <patrick@mezard.eu>
0 Copyright (c) 2014 The lldb Authors. All rights reserved.
1
2 Redistribution and use in source and binary forms, with or without
3 modification, are permitted provided that the following conditions are
4 met:
5
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above
9 copyright notice, this list of conditions and the following disclaimer
10 in the documentation and/or other materials provided with the
11 distribution.
12 * Neither the names of the authors nor the names of the
13 contributors may be used to endorse or promote products derived from
14 this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0 # Copyright 2014 The lldb Authors. All rights reserved.
1 # Use of this source code is governed by a BSD-style
2 # license that can be found in the LICENSE file.
3
4 .PHONY: all editor clean cover nuke
5
6 testbin=lldb.test
7 grep=--include=*.go
8
9 all: editor
10 go build
11 go vet
12 golint .
13 go install
14 make todo
15
16 clean:
17 go clean
18 rm -f *~ cov cov.html bad-dump good-dump lldb.test old.txt new.txt \
19 test-acidfiler0-* _test.db _wal
20
21 cover:
22 t=$(shell tempfile) ; go test -coverprofile $$t && go tool cover -html $$t && unlink $$t
23
24 editor:
25 gofmt -l -s -w *.go
26 go test -i
27 go test -timeout 1h
28
29 mem:
30 go test -c
31 ./$(testbin) -test.bench . -test.memprofile mem.out -test.memprofilerate 1 -test.timeout 24h
32 go tool pprof --lines --web --alloc_space $(testbin) mem.out
33
34 nuke: clean
35 go clean -i
36
37 todo:
38 @grep -nr $(grep) BUG * || true
39 @grep -nr $(grep) LATER * || true
40 @grep -nr $(grep) MAYBE * || true
41 @grep -nr $(grep) TODO * || true
42 @grep -nr $(grep) FIXME * || true
43 @grep -nr $(grep) ^[[:space:]]*_[[:space:]]*=[[:space:]][[:alpha:]][[:alnum:]]* * || true
44 @grep -nr $(grep) println * || true
0 lldb
1 ====
2
3 Package lldb (WIP) implements a low level database engine.
4
5 Installation: $ go get github.com/cznic/exp/lldb
6
7 Documentation: [godoc.org/github.com/cznic/exp/lldb](http://godoc.org/github.com/cznic/exp/lldb)
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 package lldb
5
6 import (
7 "encoding/hex"
8 "fmt"
9 "io/ioutil"
10 "os"
11 "path"
12 "path/filepath"
13 "runtime"
14 "strings"
15 "time"
16 )
17
18 const (
19 testDbName = "_test.db"
20 walName = "_wal"
21 )
22
23 func caller(s string, va ...interface{}) {
24 if s == "" {
25 s = strings.Repeat("%v ", len(va))
26 }
27 _, fn, fl, _ := runtime.Caller(2)
28 fmt.Fprintf(os.Stderr, "caller: %s:%d: ", path.Base(fn), fl)
29 fmt.Fprintf(os.Stderr, s, va...)
30 fmt.Fprintln(os.Stderr)
31 _, fn, fl, _ = runtime.Caller(1)
32 fmt.Fprintf(os.Stderr, "\tcallee: %s:%d: ", path.Base(fn), fl)
33 fmt.Fprintln(os.Stderr)
34 os.Stderr.Sync()
35 }
36
37 func dbg(s string, va ...interface{}) {
38 if s == "" {
39 s = strings.Repeat("%v ", len(va))
40 }
41 _, fn, fl, _ := runtime.Caller(1)
42 fmt.Fprintf(os.Stderr, "dbg %s:%d: ", path.Base(fn), fl)
43 fmt.Fprintf(os.Stderr, s, va...)
44 fmt.Fprintln(os.Stderr)
45 os.Stderr.Sync()
46 }
47
48 func TODO(...interface{}) string {
49 _, fn, fl, _ := runtime.Caller(1)
50 return fmt.Sprintf("TODO: %s:%d:\n", path.Base(fn), fl)
51 }
52
53 func use(...interface{}) {}
54
55 // ============================================================================
56
57 func now() time.Time { return time.Now() }
58
59 func hdump(b []byte) string {
60 return hex.Dump(b)
61 }
62
63 func die() {
64 os.Exit(1)
65 }
66
67 func stack() string {
68 buf := make([]byte, 1<<16)
69 return string(buf[:runtime.Stack(buf, false)])
70 }
71
72 func temp() (dir, name string) {
73 dir, err := ioutil.TempDir("", "test-lldb-")
74 if err != nil {
75 panic(err)
76 }
77
78 return dir, filepath.Join(dir, "test.tmp")
79 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 package lldb
5
6 import (
7 "bytes"
8 "errors"
9 "fmt"
10 "io"
11 "sort"
12 "strings"
13
14 "github.com/cznic/bufs"
15 "github.com/cznic/fileutil"
16 "github.com/cznic/sortutil"
17 )
18
19 const (
20 kData = 256 // [1, 512]
21 kIndex = 256 // [2, 2048]
22 kKV = 19 // Size of the key/value field in btreeDataPage
23 kSz = kKV - 1 - 7 // Content prefix size
24 kH = kKV - 7 // Content field offset for handle
25 tagBTreeDataPage = 1
26 tagBTreeIndexPage = 0
27 )
28
29 // BTree is a B+tree[1][2], i.e. a variant which speeds up
30 // enumeration/iteration of the BTree. According to its origin it can be
31 // volatile (backed only by memory) or non-volatile (backed by a non-volatile
32 // Allocator).
33 //
34 // The specific implementation of BTrees in this package are B+trees with
35 // delayed split/concatenation (discussed in e.g. [3]).
36 //
37 // Note: No BTree methods returns io.EOF for physical Filer reads/writes. The
38 // io.EOF is returned only by bTreeEnumerator methods to indicate "no more K-V
39 // pair".
40 //
41 // [1]: http://en.wikipedia.org/wiki/B+tree
42 // [2]: http://zgking.com:8080/home/donghui/publications/books/dshandbook_BTree.pdf
43 // [3]: http://people.cs.aau.dk/~simas/aalg06/UbiquitBtree.pdf
44 type BTree struct {
45 store btreeStore
46 root btree
47 collate func(a, b []byte) int
48 serial uint64
49 }
50
51 // NewBTree returns a new, memory-only BTree.
52 func NewBTree(collate func(a, b []byte) int) *BTree {
53 store := newMemBTreeStore()
54 root, err := newBTree(store)
55 if err != nil { // should not happen
56 panic(err.Error())
57 }
58
59 return &BTree{store, root, collate, 0}
60 }
61
62 // IsMem reports if t is a memory only BTree.
63 func (t *BTree) IsMem() (r bool) {
64 _, r = t.store.(*memBTreeStore)
65 return
66 }
67
68 // Clear empties the tree.
69 func (t *BTree) Clear() (err error) {
70 if t == nil {
71 err = errors.New("BTree method invoked on nil receiver")
72 return
73 }
74
75 t.serial++
76 return t.root.clear(t.store)
77 }
78
79 // Delete deletes key and its associated value from the tree.
80 func (t *BTree) Delete(key []byte) (err error) {
81 if t == nil {
82 err = errors.New("BTree method invoked on nil receiver")
83 return
84 }
85
86 t.serial++
87 _, err = t.root.extract(t.store, nil, t.collate, key)
88 return
89 }
90
91 // DeleteAny deletes one key and its associated value from the tree. If the
92 // tree is empty on return then empty is true.
93 func (t *BTree) DeleteAny() (empty bool, err error) {
94 if t == nil {
95 err = errors.New("BTree method invoked on nil receiver")
96 return
97 }
98
99 t.serial++
100 return t.root.deleteAny(t.store)
101 }
102
103 func elem(v interface{}) string {
104 switch x := v.(type) {
105 default:
106 panic("internal error")
107 case nil:
108 return "nil"
109 case bool:
110 if x {
111 return "true"
112 }
113
114 return "false"
115 case int64:
116 return fmt.Sprint(x)
117 case uint64:
118 return fmt.Sprint(x)
119 case float64:
120 s := fmt.Sprintf("%g", x)
121 if !strings.Contains(s, ".") {
122 s += "."
123 }
124 return s
125 case complex128:
126 s := fmt.Sprint(x)
127 return s[1 : len(s)-1]
128 case []byte:
129 return fmt.Sprintf("[]byte{% 02x}", x)
130 case string:
131 return fmt.Sprintf("%q", x)
132 }
133 }
134
135 // Dump outputs a human readable dump of t to w. It is usable iff t keys and
136 // values are encoded scalars (see EncodeScalars). Intended use is only for
137 // examples or debugging. Some type information is lost in the rendering, for
138 // example a float value '17.' and an integer value '17' may both output as
139 // '17'.
140 func (t *BTree) Dump(w io.Writer) (err error) {
141 enum, err := t.seekFirst()
142 if err != nil {
143 return
144 }
145
146 for {
147 bkey, bval, err := enum.current()
148 if err != nil {
149 return err
150 }
151
152 key, err := DecodeScalars(bkey)
153 if err != nil {
154 return err
155 }
156
157 val, err := DecodeScalars(bval)
158 if err != nil {
159 return err
160 }
161
162 kk := []string{}
163 if key == nil {
164 kk = []string{"null"}
165 }
166 for _, v := range key {
167 kk = append(kk, elem(v))
168 }
169 vv := []string{}
170 if val == nil {
171 vv = []string{"null"}
172 }
173 for _, v := range val {
174 vv = append(vv, elem(v))
175 }
176 skey := strings.Join(kk, ", ")
177 sval := strings.Join(vv, ", ")
178 if len(vv) > 1 {
179 sval = fmt.Sprintf("[]interface{%s}", sval)
180 }
181 if _, err = fmt.Fprintf(w, "%s → %s\n", skey, sval); err != nil {
182 return err
183 }
184
185 err = enum.next()
186 if err != nil {
187 if fileutil.IsEOF(err) {
188 err = nil
189 break
190 }
191
192 return err
193 }
194 }
195 return
196 }
197
198 // Extract is a combination of Get and Delete. If the key exists in the tree,
199 // it is returned (like Get) and also deleted from a tree in a more efficient
200 // way which doesn't walk it twice. The returned slice may be a sub-slice of
201 // buf if buf was large enough to hold the entire content. Otherwise, a newly
202 // allocated slice will be returned. It is valid to pass a nil buf.
203 func (t *BTree) Extract(buf, key []byte) (value []byte, err error) {
204 if t == nil {
205 err = errors.New("BTree method invoked on nil receiver")
206 return
207 }
208
209 t.serial++
210 return t.root.extract(t.store, buf, t.collate, key)
211 }
212
213 // First returns the first KV pair of the tree, if it exists. Otherwise key == nil
214 // and value == nil.
215 func (t *BTree) First() (key, value []byte, err error) {
216 if t == nil {
217 err = errors.New("BTree method invoked on nil receiver")
218 return
219 }
220
221 var p btreeDataPage
222 if _, p, err = t.root.first(t.store); err != nil || p == nil {
223 return
224 }
225
226 if key, err = p.key(t.store, 0); err != nil {
227 return
228 }
229
230 value, err = p.value(t.store, 0)
231 return
232 }
233
234 // Get returns the value associated with key, or nil if no such value exists.
235 // The returned slice may be a sub-slice of buf if buf was large enough to hold
236 // the entire content. Otherwise, a newly allocated slice will be returned.
237 // It is valid to pass a nil buf.
238 //
239 // Get is safe for concurrent access by multiple goroutines iff no other
240 // goroutine mutates the tree.
241 func (t *BTree) Get(buf, key []byte) (value []byte, err error) {
242 if t == nil {
243 err = errors.New("BTree method invoked on nil receiver")
244 return
245 }
246
247 buffer := bufs.GCache.Get(maxBuf)
248 defer bufs.GCache.Put(buffer)
249 if buffer, err = t.root.get(t.store, buffer, t.collate, key); buffer == nil || err != nil {
250 return
251 }
252
253 if len(buffer) != 0 {
254 // The buffer cache returns nil for empty buffers, bypass it
255 value = need(len(buffer), buf)
256 } else {
257 value = []byte{}
258 }
259 copy(value, buffer)
260 return
261 }
262
263 // Handle reports t's handle.
264 func (t *BTree) Handle() int64 {
265 return int64(t.root)
266 }
267
268 // Last returns the last KV pair of the tree, if it exists. Otherwise key == nil
269 // and value == nil.
270 func (t *BTree) Last() (key, value []byte, err error) {
271 if t == nil {
272 err = errors.New("BTree method invoked on nil receiver")
273 return
274 }
275
276 var p btreeDataPage
277 if _, p, err = t.root.last(t.store); err != nil || p == nil {
278 return
279 }
280
281 index := p.len() - 1
282 if key, err = p.key(t.store, index); err != nil {
283 return
284 }
285
286 value, err = p.value(t.store, index)
287 return
288 }
289
290 // Put combines Get and Set in a more efficient way where the tree is walked
291 // only once. The upd(ater) receives the current (key, old-value), if that
292 // exists or (key, nil) otherwise. It can then return a (new-value, true, nil)
293 // to create or overwrite the existing value in the KV pair, or (whatever,
294 // false, nil) if it decides not to create or not to update the value of the KV
295 // pair.
296 //
297 // tree.Set(k, v)
298 //
299 // conceptually equals
300 //
301 // tree.Put(k, func(k, v []byte){ return v, true }([]byte, bool))
302 //
303 // modulo the differing return values.
304 //
305 // The returned slice may be a sub-slice of buf if buf was large enough to hold
306 // the entire content. Otherwise, a newly allocated slice will be returned.
307 // It is valid to pass a nil buf.
308 func (t *BTree) Put(buf, key []byte, upd func(key, old []byte) (new []byte, write bool, err error)) (old []byte, written bool, err error) {
309 if t == nil {
310 err = errors.New("BTree method invoked on nil receiver")
311 return
312 }
313
314 t.serial++
315 return t.root.put2(buf, t.store, t.collate, key, upd)
316 }
317
318 // Seek returns an Enumerator with "position" or an error of any. Normally the
319 // position is on a KV pair such that key >= KV.key. Then hit is key == KV.key.
320 // The position is possibly "after" the last KV pair, but that is not an error.
321 //
322 // Seek is safe for concurrent access by multiple goroutines iff no other
323 // goroutine mutates the tree.
324 func (t *BTree) Seek(key []byte) (enum *BTreeEnumerator, hit bool, err error) {
325 enum0, hit, err := t.seek(key)
326 if err != nil {
327 return
328 }
329
330 enum = &BTreeEnumerator{
331 enum: enum0,
332 firstHit: hit,
333 key: append([]byte(nil), key...),
334 }
335 return
336 }
337
338 func (t *BTree) seek(key []byte) (enum *bTreeEnumerator, hit bool, err error) {
339 if t == nil {
340 err = errors.New("BTree method invoked on nil receiver")
341 return
342 }
343
344 r := &bTreeEnumerator{t: t, collate: t.collate, serial: t.serial}
345 if r.p, r.index, hit, err = t.root.seek(t.store, r.collate, key); err != nil {
346 return
347 }
348
349 enum = r
350 return
351 }
352
353 // IndexSeek returns an Enumerator with "position" or an error of any. Normally
354 // the position is on a KV pair such that key >= KV.key. Then hit is key ==
355 // KV.key. The position is possibly "after" the last KV pair, but that is not
356 // an error. The collate function originally passed to CreateBTree is used for
357 // enumerating the tree but a custom collate function c is used for IndexSeek.
358 //
359 // IndexSeek is safe for concurrent access by multiple goroutines iff no other
360 // goroutine mutates the tree.
361 func (t *BTree) IndexSeek(key []byte, c func(a, b []byte) int) (enum *BTreeEnumerator, hit bool, err error) { //TODO +test
362 enum0, hit, err := t.indexSeek(key, c)
363 if err != nil {
364 return
365 }
366
367 enum = &BTreeEnumerator{
368 enum: enum0,
369 firstHit: hit,
370 key: append([]byte(nil), key...),
371 }
372 return
373 }
374
375 func (t *BTree) indexSeek(key []byte, c func(a, b []byte) int) (enum *bTreeEnumerator, hit bool, err error) {
376 if t == nil {
377 err = errors.New("BTree method invoked on nil receiver")
378 return
379 }
380
381 r := &bTreeEnumerator{t: t, collate: t.collate, serial: t.serial}
382 if r.p, r.index, hit, err = t.root.seek(t.store, c, key); err != nil {
383 return
384 }
385
386 enum = r
387 return
388 }
389
390 // seekFirst returns an enumerator positioned on the first KV pair in the tree,
391 // if any. For an empty tree, err == io.EOF is returend.
392 //
393 // SeekFirst is safe for concurrent access by multiple goroutines iff no other
394 // goroutine mutates the tree.
395 func (t *BTree) SeekFirst() (enum *BTreeEnumerator, err error) {
396 enum0, err := t.seekFirst()
397 if err != nil {
398 return
399 }
400
401 var key []byte
402 if key, _, err = enum0.current(); err != nil {
403 return
404 }
405
406 enum = &BTreeEnumerator{
407 enum: enum0,
408 firstHit: true,
409 key: append([]byte(nil), key...),
410 }
411 return
412 }
413
414 func (t *BTree) seekFirst() (enum *bTreeEnumerator, err error) {
415 if t == nil {
416 err = errors.New("BTree method invoked on nil receiver")
417 return
418 }
419
420 var p btreeDataPage
421 if _, p, err = t.root.first(t.store); err == nil && p == nil {
422 err = io.EOF
423 }
424 if err != nil {
425 return
426 }
427
428 return &bTreeEnumerator{t: t, collate: t.collate, p: p, index: 0, serial: t.serial}, nil
429 }
430
431 // seekLast returns an enumerator positioned on the last KV pair in the tree,
432 // if any. For an empty tree, err == io.EOF is returend.
433 //
434 // SeekLast is safe for concurrent access by multiple goroutines iff no other
435 // goroutine mutates the tree.
436 func (t *BTree) SeekLast() (enum *BTreeEnumerator, err error) {
437 enum0, err := t.seekLast()
438 if err != nil {
439 return
440 }
441
442 var key []byte
443 if key, _, err = enum0.current(); err != nil {
444 return
445 }
446
447 enum = &BTreeEnumerator{
448 enum: enum0,
449 firstHit: true,
450 key: append([]byte(nil), key...),
451 }
452 return
453 }
454
455 func (t *BTree) seekLast() (enum *bTreeEnumerator, err error) {
456 if t == nil {
457 err = errors.New("BTree method invoked on nil receiver")
458 return
459 }
460
461 var p btreeDataPage
462 if _, p, err = t.root.last(t.store); err == nil && p == nil {
463 err = io.EOF
464 }
465 if err != nil {
466 return
467 }
468
469 return &bTreeEnumerator{t: t, collate: t.collate, p: p, index: p.len() - 1, serial: t.serial}, nil
470 }
471
472 // Set sets the value associated with key. Any previous value, if existed, is
473 // overwritten by the new one.
474 func (t *BTree) Set(key, value []byte) (err error) {
475 if t == nil {
476 err = errors.New("BTree method invoked on nil receiver")
477 return
478 }
479
480 t.serial++
481 dst := bufs.GCache.Get(maxBuf)
482 _, err = t.root.put(dst, t.store, t.collate, key, value, true)
483 bufs.GCache.Put(dst)
484 return
485 }
486
487 // bTreeEnumerator is a closure of a BTree and a position. It is returned from
488 // BTree.seek.
489 //
490 // NOTE: bTreeEnumerator cannot be used after its BTree was mutated after the
491 // bTreeEnumerator was acquired from any of the seek, seekFirst, seekLast
492 // methods.
493 type bTreeEnumerator struct {
494 t *BTree
495 collate func(a, b []byte) int
496 p btreeDataPage
497 index int
498 serial uint64
499 }
500
501 // Current returns the KV pair the enumerator is currently positioned on. If
502 // the position is before the first KV pair in the tree or after the last KV
503 // pair in the tree then err == io.EOF is returned.
504 //
505 // If the enumerator has been invalidated by updating the tree, ErrINVAL is
506 // returned.
507 func (e *bTreeEnumerator) current() (key, value []byte, err error) {
508 if e == nil {
509 err = errors.New("bTreeEnumerator method invoked on nil receiver")
510 return
511 }
512
513 if e.serial != e.t.serial {
514 err = &ErrINVAL{Src: "bTreeEnumerator invalidated by updating the tree"}
515 return
516 }
517
518 if e.p == nil || e.index == e.p.len() {
519 return nil, nil, io.EOF
520 }
521
522 if key, err = e.p.key(e.t.store, e.index); err != nil {
523 return
524 }
525
526 value, err = e.p.value(e.t.store, e.index)
527 return
528 }
529
530 // Next attempts to position the enumerator onto the next KV pair wrt the
531 // current position. If there is no "next" KV pair, io.EOF is returned.
532 //
533 // If the enumerator has been invalidated by updating the tree, ErrINVAL is
534 // returned.
535 func (e *bTreeEnumerator) next() (err error) {
536 if e == nil {
537 err = errors.New("bTreeEnumerator method invoked on nil receiver")
538 return
539 }
540
541 if e.serial != e.t.serial {
542 err = &ErrINVAL{Src: "bTreeEnumerator invalidated by updating the tree"}
543 return
544 }
545
546 if e.p == nil {
547 return io.EOF
548 }
549
550 switch {
551 case e.index < e.p.len()-1:
552 e.index++
553 default:
554 ph := e.p.next()
555 if ph == 0 {
556 err = io.EOF
557 break
558 }
559
560 if e.p, err = e.t.store.Get(e.p, ph); err != nil {
561 e.p = nil
562 return
563 }
564 e.index = 0
565 }
566 return
567 }
568
569 // Prev attempts to position the enumerator onto the previous KV pair wrt the
570 // current position. If there is no "previous" KV pair, io.EOF is returned.
571 //
572 // If the enumerator has been invalidated by updating the tree, ErrINVAL is
573 // returned.
574 func (e *bTreeEnumerator) prev() (err error) {
575 if e == nil {
576 err = errors.New("bTreeEnumerator method invoked on nil receiver")
577 return
578 }
579
580 if e.serial != e.t.serial {
581 err = &ErrINVAL{Src: "bTreeEnumerator invalidated by updating the tree"}
582 return
583 }
584
585 if e.p == nil {
586 return io.EOF
587 }
588
589 switch {
590 case e.index > 0:
591 e.index--
592 default:
593 ph := e.p.prev()
594 if ph == 0 {
595 err = io.EOF
596 break
597 }
598
599 if e.p, err = e.t.store.Get(e.p, ph); err != nil {
600 e.p = nil
601 return
602 }
603 e.index = e.p.len() - 1
604 }
605 return
606 }
607
608 // BTreeEnumerator captures the state of enumerating a tree. It is returned
609 // from the Seek* methods. The enumerator is aware of any mutations made to
610 // the tree in the process of enumerating it and automatically resumes the
611 // enumeration.
612 type BTreeEnumerator struct {
613 enum *bTreeEnumerator
614 err error
615 key []byte
616 firstHit bool
617 }
618
619 // Next returns the currently enumerated KV pair, if it exists and moves to the
620 // next KV in the key collation order. If there is no KV pair to return, err ==
621 // io.EOF is returned.
622 //
623 // Next is safe for concurrent access by multiple goroutines iff no other
624 // goroutine mutates the tree.
625 func (e *BTreeEnumerator) Next() (key, value []byte, err error) {
626 if err = e.err; err != nil {
627 return
628 }
629
630 canRetry := true
631 retry:
632 if e.enum.p == nil {
633 e.err = io.EOF
634 return nil, nil, e.err
635 }
636
637 if e.enum.index == e.enum.p.len() && e.enum.serial == e.enum.t.serial {
638 if err := e.enum.next(); err != nil {
639 e.err = err
640 return nil, nil, e.err
641 }
642 }
643
644 if key, value, err = e.enum.current(); err != nil {
645 if _, ok := err.(*ErrINVAL); !ok || !canRetry {
646 e.err = err
647 return
648 }
649
650 canRetry = false
651 var hit bool
652 if e.enum, hit, err = e.enum.t.seek(e.key); err != nil {
653 e.err = err
654 return
655 }
656
657 if !e.firstHit && hit {
658 err = e.enum.next()
659 if err != nil {
660 e.err = err
661 return
662 }
663 }
664
665 goto retry
666 }
667
668 e.firstHit = false
669 e.key = append([]byte(nil), key...)
670 e.err = e.enum.next()
671 return
672 }
673
674 // Prev returns the currently enumerated KV pair, if it exists and moves to the
675 // previous KV in the key collation order. If there is no KV pair to return,
676 // err == io.EOF is returned.
677 //
678 // Prev is safe for concurrent access by multiple goroutines iff no other
679 // goroutine mutates the tree.
680 func (e *BTreeEnumerator) Prev() (key, value []byte, err error) {
681 if err = e.err; err != nil {
682 return
683 }
684
685 canRetry := true
686 retry:
687 if key, value, err = e.enum.current(); err != nil {
688 if _, ok := err.(*ErrINVAL); !ok || !canRetry {
689 e.err = err
690 return
691 }
692
693 canRetry = false
694 var hit bool
695 if e.enum, hit, err = e.enum.t.seek(e.key); err != nil {
696 e.err = err
697 return
698 }
699
700 if !e.firstHit && hit {
701 err = e.enum.prev()
702 if err != nil {
703 e.err = err
704 return
705 }
706 }
707
708 goto retry
709 }
710
711 e.firstHit = false
712 e.key = append([]byte(nil), key...)
713 e.err = e.enum.prev()
714 return
715 }
716
717 // CreateBTree creates a new BTree in store. It returns the tree, its (freshly
718 // assigned) handle (for OpenBTree or RemoveBTree) or an error, if any.
719 func CreateBTree(store *Allocator, collate func(a, b []byte) int) (bt *BTree, handle int64, err error) {
720 r := &BTree{store: store, collate: collate}
721 if r.root, err = newBTree(store); err != nil {
722 return
723 }
724
725 return r, int64(r.root), nil
726 }
727
728 // OpenBTree opens a store's BTree using handle. It returns the tree or an
729 // error, if any. The same tree may be opened more than once, but operations on
730 // the separate instances should not ever overlap or void the other instances.
731 // However, the intended API usage is to open the same tree handle only once
732 // (handled by some upper layer "dispatcher").
733 func OpenBTree(store *Allocator, collate func(a, b []byte) int, handle int64) (bt *BTree, err error) {
734 r := &BTree{store: store, root: btree(handle), collate: collate}
735 b := bufs.GCache.Get(7)
736 defer bufs.GCache.Put(b)
737 if b, err = store.Get(b, handle); err != nil {
738 return
739 }
740
741 if len(b) != 7 {
742 return nil, &ErrILSEQ{Off: h2off(handle), More: "btree.go:671"}
743 }
744
745 return r, nil
746 }
747
748 // RemoveBTree removes tree, represented by handle from store. Empty trees are
749 // cheap, each uses only few bytes of the store. If there's a chance that a
750 // tree will eventually get reused (non empty again), it's recommended to
751 // not/never remove it. One advantage of such approach is a stable handle of
752 // such tree.
753 func RemoveBTree(store *Allocator, handle int64) (err error) {
754 tree, err := OpenBTree(store, nil, handle)
755 if err != nil {
756 return
757 }
758
759 if err = tree.Clear(); err != nil {
760 return
761 }
762
763 return store.Free(handle)
764 }
765
766 type btreeStore interface {
767 Alloc(b []byte) (handle int64, err error)
768 Free(handle int64) (err error)
769 Get(dst []byte, handle int64) (b []byte, err error)
770 Realloc(handle int64, b []byte) (err error)
771 }
772
773 // Read only zero bytes
774 var zeros [2 * kKV]byte
775
776 func init() {
777 if kData < 1 || kData > 512 {
778 panic(fmt.Errorf("kData %d: out of limits", kData))
779 }
780
781 if kIndex < 2 || kIndex > 2048 {
782 panic(fmt.Errorf("kIndex %d: out of limits", kIndex))
783 }
784
785 if kKV < 8 || kKV > 23 {
786 panic(fmt.Errorf("kKV %d: out of limits", kKV))
787 }
788
789 if n := len(zeros); n < 15 {
790 panic(fmt.Errorf("not enough zeros: %d", n))
791 }
792 }
793
794 type memBTreeStore struct {
795 h int64
796 m map[int64][]byte
797 }
798
799 func newMemBTreeStore() *memBTreeStore {
800 return &memBTreeStore{h: 0, m: map[int64][]byte{}}
801 }
802
803 func (s *memBTreeStore) String() string {
804 var a sortutil.Int64Slice
805 for k := range s.m {
806 a = append(a, k)
807 }
808 sort.Sort(a)
809 var sa []string
810 for _, k := range a {
811 sa = append(sa, fmt.Sprintf("%#x:|% x|", k, s.m[k]))
812 }
813 return strings.Join(sa, "\n")
814 }
815
816 func (s *memBTreeStore) Alloc(b []byte) (handle int64, err error) {
817 s.h++
818 handle = s.h
819 s.m[handle] = bpack(b)
820 return
821 }
822
823 func (s *memBTreeStore) Free(handle int64) (err error) {
824 if _, ok := s.m[handle]; !ok {
825 return &ErrILSEQ{Type: ErrOther, Off: h2off(handle), More: "btree.go:754"}
826 }
827
828 delete(s.m, handle)
829 return
830 }
831
832 func (s *memBTreeStore) Get(dst []byte, handle int64) (b []byte, err error) {
833 r, ok := s.m[handle]
834 if !ok {
835 return nil, &ErrILSEQ{Type: ErrOther, Off: h2off(handle), More: "btree.go:764"}
836 }
837
838 b = need(len(r), dst)
839 copy(b, r)
840 return
841 }
842
843 func (s *memBTreeStore) Realloc(handle int64, b []byte) (err error) {
844 if _, ok := s.m[handle]; !ok {
845 return &ErrILSEQ{Type: ErrOther, Off: h2off(handle), More: "btree.go:774"}
846 }
847
848 s.m[handle] = bpack(b)
849 return
850 }
851
852 /*
853
854 0...0 (1 bytes):
855 Flag
856
857 0
858 +---+
859 | 0 |
860 +---+
861
862 0 indicates an index page
863
864 1...count*14-1
865 "array" of items, 14 bytes each. Count of items in kIndex-1..2*kIndex+2
866
867 Count = (len(raw) - 8) / 14
868
869 0..6 7..13
870 +-------+----------+
871 | Child | DataPage |
872 +-------+----------+
873
874 Child == handle of a child index page
875 DataPage == handle of a data page
876
877 Offsets into the raw []byte:
878 Child[X] == 1+14*X
879 DataPage[X] == 8+14*X
880
881 */
882 type btreeIndexPage []byte
883
884 func newBTreeIndexPage(leftmostChild int64) (p btreeIndexPage) {
885 p = bufs.GCache.Get(1 + (kIndex+1)*2*7)[:8]
886 p[0] = tagBTreeIndexPage
887 h2b(p[1:], leftmostChild)
888 return
889 }
890
891 func (p btreeIndexPage) len() int {
892 return (len(p) - 8) / 14
893 }
894
895 func (p btreeIndexPage) child(index int) int64 {
896 return b2h(p[1+14*index:])
897 }
898
899 func (p btreeIndexPage) setChild(index int, dp int64) {
900 h2b(p[1+14*index:], dp)
901 }
902
903 func (p btreeIndexPage) dataPage(index int) int64 {
904 return b2h(p[8+14*index:])
905 }
906
907 func (p btreeIndexPage) setDataPage(index int, dp int64) {
908 h2b(p[8+14*index:], dp)
909 }
910
911 func (q btreeIndexPage) insert(index int) btreeIndexPage {
912 switch len0 := q.len(); {
913 case index < len0:
914 has := len(q)
915 need := has + 14
916 switch {
917 case cap(q) >= need:
918 q = q[:need]
919 default:
920 q = append(q, zeros[:14]...)
921 }
922 copy(q[8+14*(index+1):8+14*(index+1)+2*(len0-index)*7], q[8+14*index:])
923 case index == len0:
924 has := len(q)
925 need := has + 14
926 switch {
927 case cap(q) >= need:
928 q = q[:need]
929 default:
930 q = append(q, zeros[:14]...)
931 }
932 }
933 return q
934 }
935
936 func (p btreeIndexPage) insert3(index int, dataPage, child int64) btreeIndexPage {
937 p = p.insert(index)
938 p.setDataPage(index, dataPage)
939 p.setChild(index+1, child)
940 return p
941 }
942
943 func (p btreeIndexPage) cmp(a btreeStore, c func(a, b []byte) int, keyA []byte, keyBIndex int) (int, error) {
944 b := bufs.GCache.Get(maxBuf)
945 defer bufs.GCache.Put(b)
946 dp, err := a.Get(b, p.dataPage(keyBIndex))
947 if err != nil {
948 return 0, err
949 }
950
951 return btreeDataPage(dp).cmp(a, c, keyA, 0)
952 }
953
954 func (q btreeIndexPage) setLen(n int) btreeIndexPage {
955 q = q[:cap(q)]
956 need := 8 + 14*n
957 if need < len(q) {
958 return q[:need]
959 }
960 return append(q, make([]byte, need-len(q))...)
961 }
962
963 func (p btreeIndexPage) split(a btreeStore, root btree, ph *int64, parent int64, parentIndex int, index *int) (btreeIndexPage, error) {
964 right := newBTreeIndexPage(0)
965 canRecycle := true
966 defer func() {
967 if canRecycle {
968 bufs.GCache.Put(right)
969 }
970 }()
971 right = right.setLen(kIndex)
972 copy(right[1:1+(2*kIndex+1)*7], p[1+14*(kIndex+1):])
973 p = p.setLen(kIndex)
974 if err := a.Realloc(*ph, p); err != nil {
975 return nil, err
976 }
977
978 rh, err := a.Alloc(right)
979 if err != nil {
980 return nil, err
981 }
982
983 if parentIndex >= 0 {
984 var pp btreeIndexPage = bufs.GCache.Get(maxBuf)
985 defer bufs.GCache.Put(pp)
986 if pp, err = a.Get(pp, parent); err != nil {
987 return nil, err
988 }
989 pp = pp.insert3(parentIndex, p.dataPage(kIndex), rh)
990 if err = a.Realloc(parent, pp); err != nil {
991 return nil, err
992 }
993
994 } else {
995 nr := newBTreeIndexPage(*ph)
996 defer bufs.GCache.Put(nr)
997 nr = nr.insert3(0, p.dataPage(kIndex), rh)
998 nrh, err := a.Alloc(nr)
999 if err != nil {
1000 return nil, err
1001 }
1002
1003 if err = a.Realloc(int64(root), h2b(make([]byte, 7), nrh)); err != nil {
1004 return nil, err
1005 }
1006 }
1007 if *index > kIndex {
1008 p = right
1009 canRecycle = false
1010 *ph = rh
1011 *index -= kIndex + 1
1012 }
1013 return p, nil
1014 }
1015
1016 // p is dirty on return
1017 func (p btreeIndexPage) extract(index int) btreeIndexPage {
1018 n := p.len() - 1
1019 if index < n {
1020 sz := (n-index)*14 + 7
1021 copy(p[1+14*index:1+14*index+sz], p[1+14*(index+1):])
1022 }
1023 return p.setLen(n)
1024 }
1025
1026 // must persist all changes made
1027 func (p btreeIndexPage) underflow(a btreeStore, root, iroot, parent int64, ph *int64, parentIndex int, index *int) (btreeIndexPage, error) {
1028 lh, rh, err := checkSiblings(a, parent, parentIndex)
1029 if err != nil {
1030 return nil, err
1031 }
1032
1033 var left btreeIndexPage = bufs.GCache.Get(maxBuf)
1034 defer bufs.GCache.Put(left)
1035
1036 if lh != 0 {
1037 if left, err = a.Get(left, lh); err != nil {
1038 return nil, err
1039 }
1040
1041 if lc := btreeIndexPage(left).len(); lc > kIndex {
1042 var pp = bufs.GCache.Get(maxBuf)
1043 defer bufs.GCache.Put(pp)
1044 if pp, err = a.Get(pp, parent); err != nil {
1045 return nil, err
1046 }
1047
1048 pc := p.len()
1049 p = p.setLen(pc + 1)
1050 di, si, sz := 1+1*14, 1+0*14, (2*pc+1)*7
1051 copy(p[di:di+sz], p[si:])
1052 p.setChild(0, btreeIndexPage(left).child(lc))
1053 p.setDataPage(0, btreeIndexPage(pp).dataPage(parentIndex-1))
1054 *index++
1055 btreeIndexPage(pp).setDataPage(parentIndex-1, btreeIndexPage(left).dataPage(lc-1))
1056 left = left.setLen(lc - 1)
1057 if err = a.Realloc(parent, pp); err != nil {
1058 return nil, err
1059 }
1060
1061 if err = a.Realloc(*ph, p); err != nil {
1062 return nil, err
1063 }
1064
1065 return p, a.Realloc(lh, left)
1066 }
1067 }
1068
1069 if rh != 0 {
1070 right := bufs.GCache.Get(maxBuf)
1071 defer bufs.GCache.Put(right)
1072 if right, err = a.Get(right, rh); err != nil {
1073 return nil, err
1074 }
1075
1076 if rc := btreeIndexPage(right).len(); rc > kIndex {
1077 pp := bufs.GCache.Get(maxBuf)
1078 defer bufs.GCache.Put(pp)
1079 if pp, err = a.Get(pp, parent); err != nil {
1080 return nil, err
1081 }
1082
1083 pc := p.len()
1084 p = p.setLen(pc + 1)
1085 p.setDataPage(pc, btreeIndexPage(pp).dataPage(parentIndex))
1086 pc++
1087 p.setChild(pc, btreeIndexPage(right).child(0))
1088 btreeIndexPage(pp).setDataPage(parentIndex, btreeIndexPage(right).dataPage(0))
1089 di, si, sz := 1+0*14, 1+1*14, (2*rc+1)*7
1090 copy(right[di:di+sz], right[si:])
1091 right = btreeIndexPage(right).setLen(rc - 1)
1092 if err = a.Realloc(parent, pp); err != nil {
1093 return nil, err
1094 }
1095
1096 if err = a.Realloc(*ph, p); err != nil {
1097 return nil, err
1098 }
1099
1100 return p, a.Realloc(rh, right)
1101 }
1102 }
1103
1104 if lh != 0 {
1105 *index += left.len() + 1
1106 if left, err = left.concat(a, root, iroot, parent, lh, *ph, parentIndex-1); err != nil {
1107 return p, err
1108 }
1109
1110 p, *ph = left, lh
1111 return p, nil
1112 }
1113
1114 return p.concat(a, root, iroot, parent, *ph, rh, parentIndex)
1115 }
1116
1117 // must persist all changes made
1118 func (p btreeIndexPage) concat(a btreeStore, root, iroot, parent, ph, rh int64, parentIndex int) (btreeIndexPage, error) {
1119 pp := bufs.GCache.Get(maxBuf)
1120 defer bufs.GCache.Put(pp)
1121 pp, err := a.Get(pp, parent)
1122 if err != nil {
1123 return nil, err
1124 }
1125
1126 right := bufs.GCache.Get(maxBuf)
1127 defer bufs.GCache.Put(right)
1128 if right, err = a.Get(right, rh); err != nil {
1129 return nil, err
1130 }
1131
1132 pc := p.len()
1133 rc := btreeIndexPage(right).len()
1134 p = p.setLen(pc + rc + 1)
1135 p.setDataPage(pc, btreeIndexPage(pp).dataPage(parentIndex))
1136 di, si, sz := 1+14*(pc+1), 1+0*14, (2*rc+1)*7
1137 copy(p[di:di+sz], right[si:])
1138 if err := a.Realloc(ph, p); err != nil {
1139 return nil, err
1140 }
1141
1142 if err := a.Free(rh); err != nil {
1143 return nil, err
1144 }
1145
1146 if pc := btreeIndexPage(pp).len(); pc > 1 {
1147 if parentIndex < pc-1 {
1148 di, si, sz := 8+parentIndex*14, 8+(parentIndex+1)*14, 2*(pc-1-parentIndex)*7
1149 copy(pp[di:si+sz], pp[si:])
1150 }
1151 pp = btreeIndexPage(pp).setLen(pc - 1)
1152 return p, a.Realloc(parent, pp)
1153 }
1154
1155 if err := a.Free(iroot); err != nil {
1156 return nil, err
1157 }
1158
1159 b7 := bufs.GCache.Get(7)
1160 defer bufs.GCache.Put(b7)
1161 return p, a.Realloc(root, h2b(b7[:7], ph))
1162 }
1163
1164 /*
1165
1166 0...0 (1 bytes):
1167 Flag
1168
1169 0
1170 +---+
1171 | 1 |
1172 +---+
1173
1174 1 indicates a data page
1175
1176 1...14 (14 bytes)
1177
1178 1..7 8..14
1179 +------+------+
1180 | Prev | Next |
1181 +------+------+
1182
1183 Prev, Next == Handles of the data pages doubly linked list
1184
1185 Count = (len(raw) - 15) / (2*kKV)
1186
1187 15...count*2*kKV-1
1188 "array" of items, 2*kKV bytes each. Count of items in kData-1..2*kData
1189
1190 Item
1191 0..kKV-1 kKV..2*kKV-1
1192 +----------+--------------+
1193 | Key | Value |
1194 +----------+--------------+
1195
1196 Key/Value encoding
1197
1198 Length 0...kKV-1
1199
1200 0 1...N N+1...kKV-1
1201 +---+---------+-------------+
1202 | N | Data | Padding |
1203 +---+---------+-------------+
1204
1205 N == content length
1206 Data == Key or Value content
1207 Padding == MUST be zero bytes
1208
1209 Length >= kKV
1210
1211 0 1...kkV-8 kKV-7...kkV-1
1212 +------+-----------+--------------+
1213 | 0xFF | Data | H |
1214 +------+-----------+--------------+
1215
1216 Data == Key or Value content, first kKV-7 bytes
1217 H == Handle to THE REST of the content, w/o the first bytes in Data.
1218
1219 Offsets into the raw []byte:
1220 Key[X] == 15+2*kKV*X
1221 Value[X] == 15+kKV+2*kKV*X
1222 */
1223 type btreeDataPage []byte
1224
1225 func newBTreeDataPage() (p btreeDataPage) {
1226 p = bufs.GCache.Cget(1 + 2*7 + (kData+1)*2*kKV)[:1+2*7]
1227 p[0] = tagBTreeDataPage
1228 return
1229 }
1230
1231 func newBTreeDataPageAlloc(a btreeStore) (p btreeDataPage, h int64, err error) {
1232 p = newBTreeDataPage()
1233 h, err = a.Alloc(p)
1234 return
1235 }
1236
1237 func (p btreeDataPage) len() int {
1238 return (len(p) - 15) / (2 * kKV)
1239 }
1240
1241 func (q btreeDataPage) setLen(n int) btreeDataPage {
1242 q = q[:cap(q)]
1243 need := 15 + 2*kKV*n
1244 if need < len(q) {
1245 return q[:need]
1246 }
1247 return append(q, make([]byte, need-len(q))...)
1248 }
1249
1250 func (p btreeDataPage) prev() int64 {
1251 return b2h(p[1:])
1252 }
1253
1254 func (p btreeDataPage) next() int64 {
1255 return b2h(p[8:])
1256 }
1257
1258 func (p btreeDataPage) setPrev(h int64) {
1259 h2b(p[1:], h)
1260 }
1261
1262 func (p btreeDataPage) setNext(h int64) {
1263 h2b(p[8:], h)
1264 }
1265
1266 func (q btreeDataPage) insert(index int) btreeDataPage {
1267 switch len0 := q.len(); {
1268 case index < len0:
1269 has := len(q)
1270 need := has + 2*kKV
1271 switch {
1272 case cap(q) >= need:
1273 q = q[:need]
1274 default:
1275 q = append(q, zeros[:2*kKV]...)
1276 }
1277 q.copy(q, index+1, index, len0-index)
1278 return q
1279 case index == len0:
1280 has := len(q)
1281 need := has + 2*kKV
1282 switch {
1283 case cap(q) >= need:
1284 return q[:need]
1285 default:
1286 return append(q, zeros[:2*kKV]...)
1287 }
1288 }
1289 panic("internal error")
1290 }
1291
1292 func (p btreeDataPage) contentField(off int) (b []byte, h int64) {
1293 p = p[off:]
1294 switch n := int(p[0]); {
1295 case n >= kKV: // content has a handle
1296 b = append([]byte(nil), p[1:1+kSz]...)
1297 h = b2h(p[kH:])
1298 default: // content is embedded
1299 b, h = append([]byte(nil), p[1:1+n]...), 0
1300 }
1301 return
1302 }
1303
1304 func (p btreeDataPage) content(a btreeStore, off int) (b []byte, err error) {
1305 b, h := p.contentField(off)
1306 if h == 0 {
1307 return
1308 }
1309
1310 // content has a handle
1311 b2, err := a.Get(nil, h) //TODO buffers: Later, not a public API
1312 if err != nil {
1313 return nil, err
1314 }
1315
1316 return append(b, b2...), nil
1317 }
1318
1319 func (p btreeDataPage) setContent(a btreeStore, off int, b []byte) (err error) {
1320 p = p[off:]
1321 switch {
1322 case p[0] >= kKV: // existing content has a handle
1323 switch n := len(b); {
1324 case n < kKV:
1325 p[0] = byte(n)
1326 if err = a.Free(b2h(p[kH:])); err != nil {
1327 return
1328 }
1329 copy(p[1:], b)
1330 default:
1331 // reuse handle
1332 copy(p[1:1+kSz], b)
1333 return a.Realloc(b2h(p[kH:]), b[kSz:])
1334 }
1335 default: // existing content is embedded
1336 switch n := len(b); {
1337 case n < kKV:
1338 p[0] = byte(n)
1339 copy(p[1:], b)
1340 default:
1341 p[0] = 0xff
1342 copy(p[1:1+kSz], b)
1343 h, err := a.Alloc(b[kSz:])
1344 if err != nil {
1345 return err
1346 }
1347
1348 h2b(p[kH:], h)
1349 }
1350 }
1351 return
1352 }
1353
1354 func (p btreeDataPage) keyField(index int) (b []byte, h int64) {
1355 return p.contentField(15 + 2*kKV*index)
1356 }
1357
1358 func (p btreeDataPage) key(a btreeStore, index int) (b []byte, err error) {
1359 return p.content(a, 15+2*kKV*index)
1360 }
1361
1362 func (p btreeDataPage) valueField(index int) (b []byte, h int64) {
1363 return p.contentField(15 + kKV + 2*kKV*index)
1364 }
1365
1366 func (p btreeDataPage) value(a btreeStore, index int) (b []byte, err error) {
1367 value, err := p.content(a, 15+kKV+2*kKV*index)
1368 if err == nil && value == nil {
1369 // We have a valid page, no fetch error, the key is valid so return
1370 // non-nil data
1371 return []byte{}, nil
1372 }
1373 return value, err
1374 }
1375
1376 func (p btreeDataPage) valueCopy(a btreeStore, index int) (b []byte, err error) {
1377 if b, err = p.content(a, 15+kKV+2*kKV*index); err != nil {
1378 return
1379 }
1380
1381 return append([]byte(nil), b...), nil
1382 }
1383
1384 func (p btreeDataPage) setKey(a btreeStore, index int, key []byte) (err error) {
1385 return p.setContent(a, 15+2*kKV*index, key)
1386 }
1387
1388 func (p btreeDataPage) setValue(a btreeStore, index int, value []byte) (err error) {
1389 return p.setContent(a, 15+kKV+2*kKV*index, value)
1390 }
1391
1392 func (p btreeDataPage) cmp(a btreeStore, c func(a, b []byte) int, keyA []byte, keyBIndex int) (y int, err error) {
1393 var keyB []byte
1394 if keyB, err = p.content(a, 15+2*kKV*keyBIndex); err != nil {
1395 return
1396 }
1397
1398 return c(keyA, keyB), nil
1399 }
1400
1401 func (p btreeDataPage) copy(src btreeDataPage, di, si, n int) {
1402 do, so := 15+2*kKV*di, 15+2*kKV*si
1403 copy(p[do:do+2*kKV*n], src[so:])
1404 }
1405
1406 // {p,left} dirty on exit
1407 func (p btreeDataPage) moveLeft(left btreeDataPage, n int) (btreeDataPage, btreeDataPage) {
1408 nl, np := left.len(), p.len()
1409 left = left.setLen(nl + n)
1410 left.copy(p, nl, 0, n)
1411 p.copy(p, 0, n, np-n)
1412 return p.setLen(np - n), left
1413 }
1414
1415 func (p btreeDataPage) moveRight(right btreeDataPage, n int) (btreeDataPage, btreeDataPage) {
1416 nr, np := right.len(), p.len()
1417 right = right.setLen(nr + n)
1418 right.copy(right, n, 0, nr)
1419 right.copy(p, 0, np-n, n)
1420 return p.setLen(np - n), right
1421 }
1422
1423 func (p btreeDataPage) insertItem(a btreeStore, index int, key, value []byte) (btreeDataPage, error) {
1424 p = p.insert(index)
1425 di, sz := 15+2*kKV*index, 2*kKV
1426 copy(p[di:di+sz], zeros[:sz])
1427 if err := p.setKey(a, index, key); err != nil {
1428 return nil, err
1429 }
1430 return p, p.setValue(a, index, value)
1431 }
1432
1433 func (p btreeDataPage) split(a btreeStore, root, ph, parent int64, parentIndex, index int, key, value []byte) (btreeDataPage, error) {
1434 right, rh, err := newBTreeDataPageAlloc(a)
1435 // fails defer bufs.GCache.Put(right)
1436 if err != nil {
1437 return nil, err
1438 }
1439
1440 if next := p.next(); next != 0 {
1441 right.setNext(p.next())
1442 nxh := right.next()
1443 nx := bufs.GCache.Get(maxBuf)
1444 defer bufs.GCache.Put(nx)
1445 if nx, err = a.Get(nx, nxh); err != nil {
1446 return nil, err
1447 }
1448
1449 btreeDataPage(nx).setPrev(rh)
1450 if err = a.Realloc(nxh, nx); err != nil {
1451 return nil, err
1452 }
1453 }
1454
1455 p.setNext(rh)
1456 right.setPrev(ph)
1457 right = right.setLen(kData)
1458 right.copy(p, 0, kData, kData)
1459 p = p.setLen(kData)
1460
1461 if parentIndex >= 0 {
1462 var pp btreeIndexPage = bufs.GCache.Get(maxBuf)
1463 defer bufs.GCache.Put(pp)
1464 if pp, err = a.Get(pp, parent); err != nil {
1465 return nil, err
1466 }
1467
1468 pp = pp.insert3(parentIndex, rh, rh)
1469 if err = a.Realloc(parent, pp); err != nil {
1470 return nil, err
1471 }
1472
1473 } else {
1474 nr := newBTreeIndexPage(ph)
1475 defer bufs.GCache.Put(nr)
1476 nr = nr.insert3(0, rh, rh)
1477 nrh, err := a.Alloc(nr)
1478 if err != nil {
1479 return nil, err
1480 }
1481
1482 if err = a.Realloc(root, h2b(make([]byte, 7), nrh)); err != nil {
1483 return nil, err
1484 }
1485
1486 }
1487 if index > kData {
1488 if right, err = right.insertItem(a, index-kData, key, value); err != nil {
1489 return nil, err
1490 }
1491 } else {
1492 if p, err = p.insertItem(a, index, key, value); err != nil {
1493 return nil, err
1494 }
1495 }
1496 if err = a.Realloc(ph, p); err != nil {
1497 return nil, err
1498 }
1499
1500 return p, a.Realloc(rh, right)
1501 }
1502
1503 func (p btreeDataPage) overflow(a btreeStore, root, ph, parent int64, parentIndex, index int, key, value []byte) (btreeDataPage, error) {
1504 leftH, rightH, err := checkSiblings(a, parent, parentIndex)
1505 if err != nil {
1506 return nil, err
1507 }
1508
1509 if leftH != 0 {
1510 left := btreeDataPage(bufs.GCache.Get(maxBuf))
1511 defer bufs.GCache.Put(left)
1512 if left, err = a.Get(left, leftH); err != nil {
1513 return nil, err
1514 }
1515
1516 if left.len() < 2*kData && index > 0 {
1517
1518 p, left = p.moveLeft(left, 1)
1519 if err = a.Realloc(leftH, left); err != nil {
1520 return nil, err
1521 }
1522
1523 if p, err = p.insertItem(a, index-1, key, value); err != nil {
1524 return nil, err
1525 }
1526
1527 return p, a.Realloc(ph, p)
1528 }
1529 }
1530
1531 if rightH != 0 {
1532 right := btreeDataPage(bufs.GCache.Get(maxBuf))
1533 defer bufs.GCache.Put(right)
1534 if right, err = a.Get(right, rightH); err != nil {
1535 return nil, err
1536 }
1537
1538 if right.len() < 2*kData {
1539 if index < 2*kData {
1540 p, right = p.moveRight(right, 1)
1541 if err = a.Realloc(rightH, right); err != nil {
1542 return nil, err
1543 }
1544
1545 if p, err = p.insertItem(a, index, key, value); err != nil {
1546 return nil, err
1547 }
1548
1549 return p, a.Realloc(ph, p)
1550 } else {
1551 if right, err = right.insertItem(a, 0, key, value); err != nil {
1552 return nil, err
1553 }
1554
1555 return p, a.Realloc(rightH, right)
1556 }
1557 }
1558 }
1559 return p.split(a, root, ph, parent, parentIndex, index, key, value)
1560 }
1561
1562 func (p btreeDataPage) swap(a btreeStore, di int, value []byte, canOverwrite bool) (oldValue []byte, err error) {
1563 if oldValue, err = p.value(a, di); err != nil {
1564 return
1565 }
1566
1567 if !canOverwrite {
1568 return
1569 }
1570
1571 oldValue = append([]byte(nil), oldValue...)
1572 err = p.setValue(a, di, value)
1573 return
1574 }
1575
1576 type btreePage []byte
1577
1578 func (p btreePage) isIndex() bool {
1579 return p[0] == tagBTreeIndexPage
1580 }
1581
1582 func (p btreePage) len() int {
1583 if p.isIndex() {
1584 return btreeIndexPage(p).len()
1585 }
1586
1587 return btreeDataPage(p).len()
1588 }
1589
1590 func (p btreePage) find(a btreeStore, c func(a, b []byte) int, key []byte) (index int, ok bool, err error) {
1591 l := 0
1592 h := p.len() - 1
1593 isIndex := p.isIndex()
1594 if c == nil {
1595 c = bytes.Compare
1596 }
1597 for l <= h {
1598 index = (l + h) >> 1
1599 var cmp int
1600 if isIndex {
1601 if cmp, err = btreeIndexPage(p).cmp(a, c, key, index); err != nil {
1602 return
1603 }
1604 } else {
1605 if cmp, err = btreeDataPage(p).cmp(a, c, key, index); err != nil {
1606 return
1607 }
1608 }
1609 switch ok = cmp == 0; {
1610 case cmp > 0:
1611 l = index + 1
1612 case ok:
1613 return
1614 default:
1615 h = index - 1
1616 }
1617 }
1618 return l, false, nil
1619 }
1620
1621 // p is dirty after extract!
1622 func (p btreeDataPage) extract(a btreeStore, index int) (btreeDataPage, []byte, error) {
1623 value, err := p.valueCopy(a, index)
1624 if err != nil {
1625 return nil, nil, err
1626 }
1627
1628 if _, h := p.keyField(index); h != 0 {
1629 if err = a.Free(h); err != nil {
1630 return nil, nil, err
1631 }
1632 }
1633
1634 if _, h := p.valueField(index); h != 0 {
1635 if err = a.Free(h); err != nil {
1636 return nil, nil, err
1637 }
1638 }
1639
1640 n := p.len() - 1
1641 if index < n {
1642 p.copy(p, index, index+1, n-index)
1643 }
1644 return p.setLen(n), value, nil
1645 }
1646
1647 func checkSiblings(a btreeStore, parent int64, parentIndex int) (left, right int64, err error) {
1648 if parentIndex >= 0 {
1649 var p btreeIndexPage = bufs.GCache.Get(maxBuf)
1650 defer bufs.GCache.Put(p)
1651 if p, err = a.Get(p, parent); err != nil {
1652 return
1653 }
1654
1655 if parentIndex > 0 {
1656 left = p.child(parentIndex - 1)
1657 }
1658 if parentIndex < p.len() {
1659 right = p.child(parentIndex + 1)
1660 }
1661 }
1662 return
1663 }
1664
1665 // underflow must persist all changes made.
1666 func (p btreeDataPage) underflow(a btreeStore, root, iroot, parent, ph int64, parentIndex int) (err error) {
1667 lh, rh, err := checkSiblings(a, parent, parentIndex)
1668 if err != nil {
1669 return err
1670 }
1671
1672 if lh != 0 {
1673 left := bufs.GCache.Get(maxBuf)
1674 defer bufs.GCache.Put(left)
1675 if left, err = a.Get(left, lh); err != nil {
1676 return err
1677 }
1678
1679 if btreeDataPage(left).len()+p.len() >= 2*kData {
1680 left, p = btreeDataPage(left).moveRight(p, 1)
1681 if err = a.Realloc(lh, left); err != nil {
1682 return err
1683 }
1684
1685 return a.Realloc(ph, p)
1686 }
1687 }
1688
1689 if rh != 0 {
1690 right := bufs.GCache.Get(maxBuf)
1691 defer bufs.GCache.Put(right)
1692 if right, err = a.Get(right, rh); err != nil {
1693 return err
1694 }
1695
1696 if p.len()+btreeDataPage(right).len() > 2*kData {
1697 right, p = btreeDataPage(right).moveLeft(p, 1)
1698 if err = a.Realloc(rh, right); err != nil {
1699 return err
1700 }
1701
1702 return a.Realloc(ph, p)
1703 }
1704 }
1705
1706 if lh != 0 {
1707 left := bufs.GCache.Get(maxBuf)
1708 defer bufs.GCache.Put(left)
1709 if left, err = a.Get(left, lh); err != nil {
1710 return err
1711 }
1712
1713 if err = a.Realloc(ph, p); err != nil {
1714 return err
1715 }
1716
1717 return btreeDataPage(left).concat(a, root, iroot, parent, lh, ph, parentIndex-1)
1718 }
1719
1720 return p.concat(a, root, iroot, parent, ph, rh, parentIndex)
1721 }
1722
1723 // concat must persist all changes made.
1724 func (p btreeDataPage) concat(a btreeStore, root, iroot, parent, ph, rh int64, parentIndex int) (err error) {
1725 right := bufs.GCache.Get(maxBuf)
1726 defer bufs.GCache.Put(right)
1727 if right, err = a.Get(right, rh); err != nil {
1728 return err
1729 }
1730
1731 right, p = btreeDataPage(right).moveLeft(p, btreeDataPage(right).len())
1732 nxh := btreeDataPage(right).next()
1733 if nxh != 0 {
1734 nx := bufs.GCache.Get(maxBuf)
1735 defer bufs.GCache.Put(nx)
1736 if nx, err = a.Get(nx, nxh); err != nil {
1737 return err
1738 }
1739
1740 btreeDataPage(nx).setPrev(ph)
1741 if err = a.Realloc(nxh, nx); err != nil {
1742 return err
1743 }
1744 }
1745 p.setNext(nxh)
1746 if err = a.Free(rh); err != nil {
1747 return err
1748 }
1749
1750 pp := bufs.GCache.Get(maxBuf)
1751 defer bufs.GCache.Put(pp)
1752 if pp, err = a.Get(pp, parent); err != nil {
1753 return err
1754 }
1755
1756 if btreeIndexPage(pp).len() > 1 {
1757 pp = btreeIndexPage(pp).extract(parentIndex)
1758 btreeIndexPage(pp).setChild(parentIndex, ph)
1759 if err = a.Realloc(parent, pp); err != nil {
1760 return err
1761 }
1762
1763 return a.Realloc(ph, p)
1764 }
1765
1766 if err = a.Free(iroot); err != nil {
1767 return err
1768 }
1769
1770 if err = a.Realloc(ph, p); err != nil {
1771 return err
1772 }
1773
1774 var b7 [7]byte
1775 return a.Realloc(root, h2b(b7[:], ph))
1776 }
1777
1778 // external "root" is stable and contains the real root.
1779 type btree int64
1780
1781 func newBTree(a btreeStore) (btree, error) {
1782 r, err := a.Alloc(zeros[:7])
1783 return btree(r), err
1784 }
1785
1786 func (root btree) String(a btreeStore) string {
1787 r := bufs.GCache.Get(16)
1788 defer bufs.GCache.Put(r)
1789 r, err := a.Get(r, int64(root))
1790 if err != nil {
1791 panic(err)
1792 }
1793
1794 iroot := b2h(r)
1795 m := map[int64]bool{int64(root): true}
1796
1797 s := []string{fmt.Sprintf("tree %#x -> %#x\n====", root, iroot)}
1798 if iroot == 0 {
1799 return s[0]
1800 }
1801
1802 var f func(int64, string)
1803 f = func(h int64, ind string) {
1804 if m[h] {
1805 return
1806 }
1807
1808 m[h] = true
1809 var b btreePage = bufs.GCache.Get(maxBuf)
1810 defer bufs.GCache.Put(b)
1811 var err error
1812 if b, err = a.Get(b, h); err != nil {
1813 panic(err)
1814 }
1815
1816 s = append(s, fmt.Sprintf("%s@%#x", ind, h))
1817 switch b.isIndex() {
1818 case true:
1819 da := []int64{}
1820 b := btreeIndexPage(b)
1821 for i := 0; i < b.len(); i++ {
1822 c, d := b.child(i), b.dataPage(i)
1823 s = append(s, fmt.Sprintf("%schild[%d] %#x dataPage[%d] %#x", ind, i, c, i, d))
1824 da = append(da, c)
1825 da = append(da, d)
1826 }
1827 i := b.len()
1828 c := b.child(i)
1829 s = append(s, fmt.Sprintf("%schild[%d] %#x", ind, i, c))
1830 for _, c := range da {
1831 f(c, ind+" ")
1832 }
1833 f(c, ind+" ")
1834 case false:
1835 b := btreeDataPage(b)
1836 s = append(s, fmt.Sprintf("%sprev %#x next %#x", ind, b.prev(), b.next()))
1837 for i := 0; i < b.len(); i++ {
1838 k, err := b.key(a, i)
1839 if err != nil {
1840 panic(err)
1841 }
1842
1843 v, err := b.value(a, i)
1844 if err != nil {
1845 panic(err)
1846 }
1847
1848 s = append(s, fmt.Sprintf("%sK[%d]|% x| V[%d]|% x|", ind, i, k, i, v))
1849 }
1850 }
1851 }
1852
1853 f(int64(iroot), "")
1854 return strings.Join(s, "\n")
1855 }
1856
1857 func (root btree) put(dst []byte, a btreeStore, c func(a, b []byte) int, key, value []byte, canOverwrite bool) (prev []byte, err error) {
1858 prev, _, err = root.put2(dst, a, c, key, func(key, old []byte) (new []byte, write bool, err error) {
1859 new, write = value, true
1860 return
1861 })
1862 return
1863 }
1864
1865 func (root btree) put2(dst []byte, a btreeStore, c func(a, b []byte) int, key []byte, upd func(key, old []byte) (new []byte, write bool, err error)) (old []byte, written bool, err error) {
1866 var r, value []byte
1867 if r, err = a.Get(dst, int64(root)); err != nil {
1868 return
1869 }
1870
1871 iroot := b2h(r)
1872 var h int64
1873 if iroot == 0 {
1874 p := newBTreeDataPage()
1875 defer bufs.GCache.Put(p)
1876 if value, written, err = upd(key, nil); err != nil || !written {
1877 return
1878 }
1879
1880 if p, err = p.insertItem(a, 0, key, value); err != nil {
1881 return
1882 }
1883
1884 h, err = a.Alloc(p)
1885 if err != nil {
1886 return nil, true, err
1887 }
1888
1889 err = a.Realloc(int64(root), h2b(r, h)[:7])
1890 return
1891 }
1892
1893 parentIndex := -1
1894 var parent int64
1895 ph := iroot
1896
1897 p := bufs.GCache.Get(maxBuf)
1898 defer bufs.GCache.Put(p)
1899
1900 for {
1901 if p, err = a.Get(p[:cap(p)], ph); err != nil {
1902 return
1903 }
1904
1905 var index int
1906 var ok bool
1907
1908 if index, ok, err = btreePage(p).find(a, c, key); err != nil {
1909 return
1910 }
1911
1912 switch {
1913 case ok: // Key found
1914 if btreePage(p).isIndex() {
1915 ph = btreeIndexPage(p).dataPage(index)
1916 if p, err = a.Get(p, ph); err != nil {
1917 return
1918 }
1919
1920 if old, err = btreeDataPage(p).valueCopy(a, 0); err != nil {
1921 return
1922 }
1923
1924 if value, written, err = upd(key, old); err != nil || !written {
1925 return
1926 }
1927
1928 if _, err = btreeDataPage(p).swap(a, 0, value, true); err != nil {
1929 return
1930 }
1931
1932 err = a.Realloc(ph, p)
1933 return
1934 }
1935
1936 if old, err = btreeDataPage(p).valueCopy(a, index); err != nil {
1937 return
1938 }
1939
1940 if value, written, err = upd(key, old); err != nil || !written {
1941 return
1942 }
1943
1944 if _, err = btreeDataPage(p).swap(a, index, value, true); err != nil {
1945 return
1946 }
1947
1948 err = a.Realloc(ph, p)
1949 return
1950 case btreePage(p).isIndex():
1951 if btreePage(p).len() > 2*kIndex {
1952 if p, err = btreeIndexPage(p).split(a, root, &ph, parent, parentIndex, &index); err != nil {
1953 return
1954 }
1955 }
1956 parentIndex = index
1957 parent = ph
1958 ph = btreeIndexPage(p).child(index)
1959 default:
1960 if value, written, err = upd(key, nil); err != nil || !written {
1961 return
1962 }
1963
1964 if btreePage(p).len() < 2*kData { // page is not full
1965 if p, err = btreeDataPage(p).insertItem(a, index, key, value); err != nil {
1966 return
1967 }
1968
1969 err = a.Realloc(ph, p)
1970 return
1971 }
1972
1973 // page is full
1974 p, err = btreeDataPage(p).overflow(a, int64(root), ph, parent, parentIndex, index, key, value)
1975 return
1976 }
1977 }
1978 }
1979
1980 //TODO actually use 'dst' to return 'value'
1981 func (root btree) get(a btreeStore, dst []byte, c func(a, b []byte) int, key []byte) (b []byte, err error) {
1982 var r []byte
1983 if r, err = a.Get(dst, int64(root)); err != nil {
1984 return
1985 }
1986
1987 iroot := b2h(r)
1988 if iroot == 0 {
1989 return
1990 }
1991
1992 ph := iroot
1993
1994 for {
1995 var p btreePage
1996 if p, err = a.Get(p, ph); err != nil {
1997 return
1998 }
1999
2000 var index int
2001 var ok bool
2002 if index, ok, err = p.find(a, c, key); err != nil {
2003 return
2004 }
2005
2006 switch {
2007 case ok:
2008 if p.isIndex() {
2009 dh := btreeIndexPage(p).dataPage(index)
2010 dp, err := a.Get(dst, dh)
2011 if err != nil {
2012 return nil, err
2013 }
2014
2015 return btreeDataPage(dp).value(a, 0)
2016 }
2017
2018 return btreeDataPage(p).value(a, index)
2019 case p.isIndex():
2020 ph = btreeIndexPage(p).child(index)
2021 default:
2022 return
2023 }
2024 }
2025 }
2026
2027 //TODO actually use 'dst' to return 'value'
2028 func (root btree) extract(a btreeStore, dst []byte, c func(a, b []byte) int, key []byte) (value []byte, err error) {
2029 var r []byte
2030 if r, err = a.Get(dst, int64(root)); err != nil {
2031 return
2032 }
2033
2034 iroot := b2h(r)
2035 if iroot == 0 {
2036 return
2037 }
2038
2039 ph := iroot
2040 parentIndex := -1
2041 var parent int64
2042
2043 p := bufs.GCache.Get(maxBuf)
2044 defer bufs.GCache.Put(p)
2045
2046 for {
2047 if p, err = a.Get(p[:cap(p)], ph); err != nil {
2048 return
2049 }
2050
2051 var index int
2052 var ok bool
2053 if index, ok, err = btreePage(p).find(a, c, key); err != nil {
2054 return
2055 }
2056
2057 if ok {
2058 if btreePage(p).isIndex() {
2059 dph := btreeIndexPage(p).dataPage(index)
2060 dp, err := a.Get(dst, dph)
2061 if err != nil {
2062 return nil, err
2063 }
2064
2065 if btreeDataPage(dp).len() > kData {
2066 if dp, value, err = btreeDataPage(dp).extract(a, 0); err != nil {
2067 return nil, err
2068 }
2069
2070 return value, a.Realloc(dph, dp)
2071 }
2072
2073 if btreeIndexPage(p).len() < kIndex && ph != iroot {
2074 var err error
2075 if p, err = btreeIndexPage(p).underflow(a, int64(root), iroot, parent, &ph, parentIndex, &index); err != nil {
2076 return nil, err
2077 }
2078 }
2079 parentIndex = index + 1
2080 parent = ph
2081 ph = btreeIndexPage(p).child(parentIndex)
2082 continue
2083 }
2084
2085 p, value, err = btreeDataPage(p).extract(a, index)
2086 if btreePage(p).len() >= kData {
2087 err = a.Realloc(ph, p)
2088 return
2089 }
2090
2091 if ph != iroot {
2092 err = btreeDataPage(p).underflow(a, int64(root), iroot, parent, ph, parentIndex)
2093 return
2094 }
2095
2096 if btreePage(p).len() == 0 {
2097 if err = a.Free(ph); err != nil {
2098 return
2099 }
2100
2101 err = a.Realloc(int64(root), zeros[:7])
2102 return
2103 }
2104 err = a.Realloc(ph, p)
2105 return
2106 }
2107
2108 if !btreePage(p).isIndex() {
2109 return
2110 }
2111
2112 if btreePage(p).len() < kIndex && ph != iroot {
2113 if p, err = btreeIndexPage(p).underflow(a, int64(root), iroot, parent, &ph, parentIndex, &index); err != nil {
2114 return nil, err
2115 }
2116 }
2117 parentIndex = index
2118 parent = ph
2119 ph = btreeIndexPage(p).child(index)
2120 }
2121 }
2122
2123 func (root btree) deleteAny(a btreeStore) (bool, error) {
2124 r := bufs.GCache.Get(7)
2125 defer bufs.GCache.Put(r)
2126 var err error
2127 if r, err = a.Get(r, int64(root)); err != nil {
2128 return false, err
2129 }
2130
2131 iroot := b2h(r)
2132 if iroot == 0 {
2133 return true, nil
2134 }
2135
2136 ph := iroot
2137 parentIndex := -1
2138 var parent int64
2139 p := bufs.GCache.Get(maxBuf)
2140 defer bufs.GCache.Put(p)
2141
2142 for {
2143 if p, err = a.Get(p, ph); err != nil {
2144 return false, err
2145 }
2146
2147 index := btreePage(p).len() / 2
2148 if btreePage(p).isIndex() {
2149 dph := btreeIndexPage(p).dataPage(index)
2150 dp := bufs.GCache.Get(maxBuf)
2151 defer bufs.GCache.Put(dp)
2152 if dp, err = a.Get(dp, dph); err != nil {
2153 return false, err
2154 }
2155
2156 if btreeDataPage(dp).len() > kData {
2157 if dp, _, err = btreeDataPage(dp).extract(a, 0); err != nil {
2158 return false, err
2159 }
2160
2161 return false, a.Realloc(dph, dp)
2162 }
2163
2164 if btreeIndexPage(p).len() < kIndex && ph != iroot {
2165 if p, err = btreeIndexPage(p).underflow(a, int64(root), iroot, parent, &ph, parentIndex, &index); err != nil {
2166 return false, err
2167 }
2168 }
2169 parentIndex = index + 1
2170 parent = ph
2171 ph = btreeIndexPage(p).child(parentIndex)
2172 continue
2173 }
2174
2175 p, _, err = btreeDataPage(p).extract(a, index)
2176 if btreePage(p).len() >= kData {
2177 err = a.Realloc(ph, p)
2178 return false, err
2179 }
2180
2181 if ph != iroot {
2182 err = btreeDataPage(p).underflow(a, int64(root), iroot, parent, ph, parentIndex)
2183 return false, err
2184 }
2185
2186 if btreePage(p).len() == 0 {
2187 if err = a.Free(ph); err != nil {
2188 return true, err
2189 }
2190
2191 return true, a.Realloc(int64(root), zeros[:7])
2192 }
2193
2194 return false, a.Realloc(ph, p)
2195 }
2196 }
2197
2198 func (root btree) first(a btreeStore) (ph int64, p btreeDataPage, err error) {
2199 r := bufs.GCache.Get(7)
2200 defer bufs.GCache.Put(r)
2201 if r, err = a.Get(r, int64(root)); err != nil {
2202 return
2203 }
2204
2205 for ph = b2h(r); ph != 0; ph = btreeIndexPage(p).child(0) {
2206 if p, err = a.Get(p, ph); err != nil {
2207 return
2208 }
2209
2210 if !btreePage(p).isIndex() {
2211 break
2212 }
2213 }
2214
2215 return
2216 }
2217
2218 func (root btree) last(a btreeStore) (ph int64, p btreeDataPage, err error) {
2219 r := bufs.GCache.Get(7)
2220 defer bufs.GCache.Put(r)
2221 if r, err = a.Get(r, int64(root)); err != nil {
2222 return
2223 }
2224
2225 for ph = b2h(r); ph != 0; ph = btreeIndexPage(p).child(btreeIndexPage(p).len()) {
2226 if p, err = a.Get(p, ph); err != nil {
2227 return
2228 }
2229
2230 if !btreePage(p).isIndex() {
2231 break
2232 }
2233 }
2234
2235 return
2236 }
2237
2238 // key >= p[index].key
2239 func (root btree) seek(a btreeStore, c func(a, b []byte) int, key []byte) (p btreeDataPage, index int, equal bool, err error) {
2240 r := bufs.GCache.Get(7)
2241 defer bufs.GCache.Put(r)
2242 if r, err = a.Get(r, int64(root)); err != nil {
2243 return
2244 }
2245
2246 for ph := b2h(r); ph != 0; ph = btreeIndexPage(p).child(index) {
2247 if p, err = a.Get(p, ph); err != nil {
2248 break
2249 }
2250
2251 if index, equal, err = btreePage(p).find(a, c, key); err != nil {
2252 break
2253 }
2254
2255 if equal {
2256 if !btreePage(p).isIndex() {
2257 break
2258 }
2259
2260 p, err = a.Get(p, btreeIndexPage(p).dataPage(index))
2261 index = 0
2262 break
2263 }
2264
2265 if !btreePage(p).isIndex() {
2266 break
2267 }
2268 }
2269 return
2270 }
2271
2272 func (root btree) clear(a btreeStore) (err error) {
2273 r := bufs.GCache.Get(7)
2274 defer bufs.GCache.Put(r)
2275 if r, err = a.Get(r, int64(root)); err != nil {
2276 return
2277 }
2278
2279 iroot := b2h(r)
2280 if iroot == 0 {
2281 return
2282 }
2283
2284 if err = root.clear2(a, iroot); err != nil {
2285 return
2286 }
2287
2288 var b [7]byte
2289 return a.Realloc(int64(root), b[:])
2290 }
2291
2292 func (root btree) clear2(a btreeStore, ph int64) (err error) {
2293 var p = bufs.GCache.Get(maxBuf)
2294 defer bufs.GCache.Put(p)
2295 if p, err = a.Get(p, ph); err != nil {
2296 return
2297 }
2298
2299 switch btreePage(p).isIndex() {
2300 case true:
2301 ip := btreeIndexPage(p)
2302 for i := 0; i <= ip.len(); i++ {
2303 root.clear2(a, ip.child(i))
2304
2305 }
2306 case false:
2307 dp := btreeDataPage(p)
2308 for i := 0; i < dp.len(); i++ {
2309 if err = dp.setKey(a, i, nil); err != nil {
2310 return
2311 }
2312
2313 if err = dp.setValue(a, i, nil); err != nil {
2314 return
2315 }
2316 }
2317 }
2318 return a.Free(ph)
2319 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 package lldb
5
6 import (
7 "bytes"
8 "crypto/sha1"
9 "encoding/binary"
10 "encoding/hex"
11 "flag"
12 "fmt"
13 "io"
14 "io/ioutil"
15 "math"
16 "math/rand"
17 "os"
18 "runtime"
19 "sort"
20 "strings"
21 "testing"
22
23 "github.com/cznic/fileutil"
24 "github.com/cznic/mathutil"
25 )
26
27 var (
28 testFrom = flag.Uint("from", 0, "test I [-from, -N)")
29 noGrow = flag.Bool("noGrow", false, "check only embeded keys/values")
30 )
31
32 func verifyPageLinks(a btreeStore, tree btree, n int) (err error) {
33 var p btreeDataPage
34 var ph int64
35 if ph, p, err = tree.first(a); err != nil {
36 return
37 }
38
39 if n == 0 {
40 if ph != 0 || p != nil {
41 return fmt.Errorf("first() should returned nil page")
42 }
43
44 ph2, p2, err := tree.last(a)
45 if err != nil {
46 return err
47 }
48
49 if ph2 != 0 || p2 != nil {
50 return fmt.Errorf("last() should returned nil page")
51 }
52
53 }
54
55 n0 := n
56 var prev int64
57 var lastKey []byte
58 for ph != 0 {
59 if p, err = a.Get(nil, ph); err != nil {
60 return
61 }
62
63 if g, e := p.prev(), prev; g != e {
64 return fmt.Errorf("broken L-R DLL chain: p %d p.prev %d, exp %d", ph, g, e)
65 }
66
67 for i := 0; i < p.len(); i++ {
68 key, err := p.key(a, i)
69 if err != nil {
70 return err
71 }
72
73 if key == nil {
74 return fmt.Errorf("nil key")
75 }
76
77 if lastKey != nil && !(bytes.Compare(lastKey, key) < 0) {
78 return fmt.Errorf("L-R key ordering broken")
79 }
80
81 lastKey = key
82 n--
83 }
84
85 prev, ph = ph, p.next()
86 }
87
88 if n != 0 {
89 return fmt.Errorf("# of keys off by %d (L-R)", n)
90 }
91
92 n = n0
93 if ph, p, err = tree.last(a); err != nil {
94 return
95 }
96
97 lastKey = nil
98 var next int64
99
100 for ph != 0 {
101 if p, err = a.Get(nil, ph); err != nil {
102 return
103 }
104
105 if g, e := p.next(), next; g != e {
106 return fmt.Errorf("broken R-L DLL chain")
107 }
108
109 for i := p.len() - 1; i >= 0; i-- {
110 key, err := p.key(a, i)
111 if err != nil {
112 return err
113 }
114
115 if key == nil {
116 return fmt.Errorf("nil key")
117 }
118
119 if lastKey != nil && !(bytes.Compare(key, lastKey) < 0) {
120 return fmt.Errorf("R-L key ordering broken")
121 }
122
123 lastKey = key
124 n--
125 }
126
127 next, ph = ph, p.prev()
128 }
129
130 if n != 0 {
131 return fmt.Errorf("# of keys off by %d (R-L)", n)
132 }
133
134 return
135 }
136
137 func testBTreePut1(t *testing.T, nf func() btreeStore, grow, from, to, xor int64) (tree btree) {
138 if *noGrow {
139 grow = 0
140 }
141
142 a := nf()
143 if a == nil {
144 t.Fatal(a)
145 }
146
147 var err error
148 tree, err = newBTree(a)
149 if err != nil {
150 t.Fatal(err)
151 }
152
153 if err := verifyPageLinks(a, tree, 0); err != nil {
154 t.Fatal(err)
155 }
156
157 // Write and read back
158 var k, v, prevValue [7]byte
159
160 n := 0
161 for i := from; i < to; i++ {
162 h2b(k[:], 0x0100000000+i^xor)
163 h2b(v[:], 0x0200000000+i^xor)
164 kk := append(make([]byte, grow*i), k[:]...)
165 vv := append(make([]byte, grow*i), v[:]...)
166 prev, err := tree.put(nil, a, nil, kk, vv, true)
167 if err != nil || len(prev) != 0 {
168 t.Fatal(i, prev, err)
169 }
170
171 var buf []byte
172 if buf, err = tree.get(a, nil, nil, kk); err != nil {
173 t.Fatal(err)
174 }
175
176 if !bytes.Equal(buf, vv) {
177 t.Fatalf("\nK %sG %sE %s%s", hex.Dump(kk), hex.Dump(buf), hex.Dump(vv), tree.String(a))
178 }
179
180 n++
181 }
182
183 if err := verifyPageLinks(a, tree, n); err != nil {
184 t.Fatalf("%s\n%s", err, tree.String(a))
185 }
186
187 // Overwrite, read and extract
188 for i := from; i < to; i++ {
189 h2b(k[:], 0x0100000000+i^xor)
190 h2b(prevValue[:], 0x0200000000+i^xor)
191 h2b(v[:], 0x0300000000+i^xor)
192 kk := append(make([]byte, grow*i), k[:]...)
193 vv := append(make([]byte, grow*i), v[:]...)
194 expPrev := append(make([]byte, grow*i), prevValue[:]...)
195 gotPrev, err := tree.put(nil, a, nil, kk, vv, true)
196 if err != nil {
197 t.Fatal(i, err)
198 }
199
200 if !bytes.Equal(gotPrev, expPrev) {
201 t.Fatalf("\nK %sG %sE %s%s", hex.Dump(kk), hex.Dump(gotPrev), hex.Dump(expPrev), tree.String(a))
202 }
203
204 var buf []byte
205 if buf, err = tree.get(a, nil, nil, kk); err != nil {
206 t.Fatal(err)
207 }
208
209 if !bytes.Equal(buf, vv) {
210 t.Fatalf("\n%s%s%s%s", hex.Dump(kk), hex.Dump(buf), hex.Dump(vv), tree.String(a))
211 }
212
213 buf = nil
214 if buf, err = tree.extract(a, nil, nil, kk); err != nil {
215 t.Fatal(err)
216 }
217
218 if !bytes.Equal(buf, vv) {
219 t.Fatalf("i %d, from [%d, %d)\nK %sG %sE %s%s", i, from, to, hex.Dump(kk), hex.Dump(buf), hex.Dump(vv), tree.String(a))
220 }
221
222 buf = nil
223 if buf, err = tree.get(a, nil, nil, kk); err != nil {
224 t.Fatal(err)
225 }
226
227 if buf != nil {
228 t.Fatalf("\nK %sB %s%s", hex.Dump(kk), hex.Dump(buf), tree.String(a))
229 }
230
231 buf = nil
232 if buf, err = tree.extract(a, nil, nil, kk); err != nil {
233 t.Fatal(err)
234 }
235
236 if buf != nil {
237 t.Fatalf("\n%s\n%s%s", hex.Dump(kk), hex.Dump(buf), tree.String(a))
238 }
239
240 n--
241 if err := verifyPageLinks(a, tree, n); err != nil {
242 t.Fatalf("%s\n%s", err, tree.String(a))
243 }
244 }
245
246 return
247 }
248
249 var xors = [...]int64{0, 0xffffffff, 0x55555555, 0xaaaaaaaa}
250
251 func TestBTreePutGetExtract(t *testing.T) {
252 N := int64(3 * kData)
253 from := int64(*testFrom)
254
255 for grow := 0; grow < 2; grow++ {
256 for _, x := range xors {
257 var s *memBTreeStore
258 tree := testBTreePut1(t, func() btreeStore { s = newMemBTreeStore(); return s }, int64(grow), from, N, x)
259 if err := verifyPageLinks(s, tree, 0); err != nil {
260 t.Fatal(err)
261 }
262
263 if g, e := len(s.m), 1; g != e {
264 t.Fatalf("leak(s) %d %d\n%s", g, e, s)
265 }
266 }
267 }
268 }
269
270 func testBTreePut2(t *testing.T, nf func() btreeStore, grow, n int) (tree btree) {
271 if *noGrow {
272 grow = 0
273 }
274 rng, err := mathutil.NewFC32(math.MinInt32, math.MaxInt32, true)
275 if err != nil {
276 t.Fatal(err)
277 }
278
279 a := nf()
280 if a == nil {
281 t.Fatal(a)
282 }
283
284 tree, err = newBTree(a)
285 if err != nil {
286 t.Fatal(err)
287 }
288
289 var k, v [7]byte
290 for i := 0; i < n; i++ {
291 ik, iv := int64(rng.Next()), int64(rng.Next())
292 h2b(k[:], ik)
293 h2b(v[:], iv)
294 kk := append(make([]byte, grow*i), k[:]...)
295 vv := append(make([]byte, grow*i), v[:]...)
296 prev, err := tree.put(nil, a, nil, kk, vv, true)
297 if err != nil || len(prev) != 0 {
298 t.Fatal(i, prev, err)
299 }
300
301 var buf []byte
302 if buf, err = tree.get(a, nil, nil, kk); err != nil {
303 t.Fatal(err)
304 }
305
306 if !bytes.Equal(buf, vv) {
307 t.Fatalf("\n%s%s%s%s", hex.Dump(kk), hex.Dump(buf), hex.Dump(vv), tree.String(a))
308 }
309 }
310
311 if err := verifyPageLinks(a, tree, n); err != nil {
312 t.Fatalf("%s\n%s\n", err, tree.String(a))
313 }
314
315 rng.Seek(0)
316 for i := 0; i < n; i++ {
317 ik, iv := int64(rng.Next()), int64(rng.Next())
318 h2b(k[:], ik)
319 h2b(v[:], iv)
320 kk := append(make([]byte, grow*i), k[:]...)
321 vv := append(make([]byte, grow*i), v[:]...)
322 var buf []byte
323 buf, err := tree.extract(a, nil, nil, kk)
324 if err != nil {
325 t.Fatal(i, err)
326 }
327
328 if !bytes.Equal(buf, vv) {
329 t.Fatalf("\n%s\n%s\n%s\n%s", hex.Dump(kk), hex.Dump(buf), hex.Dump(vv), tree.String(a))
330 }
331
332 if err := verifyPageLinks(a, tree, n-i-1); err != nil {
333 t.Fatalf("%s\n%s", err, tree.String(a))
334 }
335 }
336
337 return
338 }
339
340 func TestBTreePutGetExtractRnd(t *testing.T) {
341 N := *testN
342
343 for grow := 0; grow < 2; grow++ {
344 var s *memBTreeStore
345 tree := testBTreePut2(t, func() btreeStore { s = newMemBTreeStore(); return s }, grow, N)
346 if err := verifyPageLinks(s, tree, 0); err != nil {
347 t.Fatal(err)
348 }
349
350 if g, e := len(s.m), 1; g != e {
351 t.Fatalf("leak(s) %d %d\n%s", g, e, s)
352 }
353 }
354 }
355
356 func benchmarkBTreePut(b *testing.B, v []byte) {
357 b.StopTimer()
358 rng := rand.New(rand.NewSource(42))
359 ka := make([][7]byte, b.N)
360 for _, v := range ka {
361 h2b(v[:], int64(rng.Int63()))
362 }
363 a := newMemBTreeStore()
364 tree, err := newBTree(a)
365 if err != nil {
366 b.Fatal(err)
367 }
368
369 runtime.GC()
370 b.StartTimer()
371 for _, k := range ka {
372 tree.put(nil, a, bytes.Compare, k[:], v, true)
373 }
374 }
375
376 func BenchmarkBTreePut1(b *testing.B) {
377 v := make([]byte, 1)
378 benchmarkBTreePut(b, v)
379 }
380
381 func BenchmarkBTreePut8(b *testing.B) {
382 v := make([]byte, 8)
383 benchmarkBTreePut(b, v)
384 }
385
386 func BenchmarkBTreePut16(b *testing.B) {
387 v := make([]byte, 16)
388 benchmarkBTreePut(b, v)
389 }
390
391 func BenchmarkBTreePut32(b *testing.B) {
392 v := make([]byte, 32)
393 benchmarkBTreePut(b, v)
394 }
395
396 func benchmarkBTreeGet(b *testing.B, v []byte) {
397 b.StopTimer()
398 rng := rand.New(rand.NewSource(42))
399 ka := make([][7]byte, b.N)
400 for _, v := range ka {
401 h2b(v[:], int64(rng.Int63()))
402 }
403 a := newMemBTreeStore()
404 tree, err := newBTree(a)
405 if err != nil {
406 b.Fatal(err)
407 }
408
409 for _, k := range ka {
410 tree.put(nil, a, bytes.Compare, k[:], v, true)
411 }
412 buf := make([]byte, len(v))
413 runtime.GC()
414 b.StartTimer()
415 for _, k := range ka {
416 tree.get(a, buf, bytes.Compare, k[:])
417 }
418 }
419
420 func BenchmarkBTreeGet1(b *testing.B) {
421 v := make([]byte, 1)
422 benchmarkBTreeGet(b, v)
423 }
424
425 func BenchmarkBTreeGet8(b *testing.B) {
426 v := make([]byte, 8)
427 benchmarkBTreeGet(b, v)
428 }
429
430 func BenchmarkBTreeGet16(b *testing.B) {
431 v := make([]byte, 16)
432 benchmarkBTreeGet(b, v)
433 }
434
435 func BenchmarkBTreeGet32(b *testing.B) {
436 v := make([]byte, 32)
437 benchmarkBTreeGet(b, v)
438 }
439
440 func TestbTreeSeek(t *testing.T) {
441 N := int64(*testN)
442
443 tree := NewBTree(nil)
444
445 // Fill
446 for i := int64(1); i <= N; i++ {
447 tree.Set(enc8(10*i), enc8(10*i+1))
448 }
449
450 // Check
451 a, root := tree.store, tree.root
452 for i := int64(1); i <= N; i++ {
453 // Exact match
454 lowKey := enc8(10*i - 1)
455 key := enc8(10 * i)
456 highKey := enc8(10*i + 1)
457 p, index, eq, err := root.seek(a, nil, key)
458 if err != nil {
459 t.Fatal(err)
460 }
461
462 if !eq {
463 t.Fatal(i)
464 }
465
466 if btreePage(p).isIndex() {
467 t.Fatal(i, "need btreeDataPage")
468 }
469
470 dp := btreeDataPage(p)
471 n := dp.len()
472 if n < 0 || n > 2*kData {
473 t.Fatal(i, n)
474 }
475
476 if index < 0 || index >= n {
477 t.Fatal(index)
478 }
479
480 g, err := dp.key(a, index)
481 if err != nil {
482 t.Fatal(err)
483 }
484
485 if !bytes.Equal(g, key) {
486 t.Fatal(i)
487 }
488
489 g, err = dp.value(a, index)
490 if err != nil {
491 t.Fatal(err)
492 }
493
494 value := enc8(10*i + 1)
495 if !bytes.Equal(g, value) {
496 t.Fatal(i)
497 }
498
499 // Nonexistent "low" key. Search for 9 should return the key 10.
500 p, index, eq, err = root.seek(a, nil, lowKey)
501 if err != nil {
502 t.Fatal(err)
503 }
504
505 if eq {
506 t.Fatal(i)
507 }
508
509 if btreePage(p).isIndex() {
510 t.Fatal(i, "need btreeDataPage")
511 }
512
513 dp = btreeDataPage(p)
514 n = dp.len()
515 if n < 0 || n > 2*kData {
516 t.Fatal(i, n)
517 }
518
519 if index < 0 || index > n {
520 t.Fatal(index, n)
521 }
522
523 if index == n {
524 ph := dp.next()
525 index = 0
526 if dp, err = a.Get(p, ph); err != nil {
527 t.Fatal(err)
528 }
529 }
530
531 g, err = dp.key(a, index)
532 if err != nil {
533 t.Fatal(err)
534 }
535
536 expKey := key
537 if !bytes.Equal(g, expKey) {
538 fmt.Println(root.String(a))
539 //t.Fatalf("%d low|% x| g|% x| e|% x|", i, lowKey, g, expKey)
540 }
541
542 g, err = dp.value(a, index)
543 if err != nil {
544 t.Fatal(err)
545 }
546
547 value = enc8(10*i + 1)
548 if !bytes.Equal(g, value) {
549 t.Fatal(i)
550 }
551
552 // Nonexistent "high" key. Search for 11 should return the key 20.
553 p, index, eq, err = root.seek(a, nil, highKey)
554 if err != nil {
555 t.Fatal(err)
556 }
557
558 if eq {
559 t.Fatal(i)
560 }
561
562 if btreePage(p).isIndex() {
563 t.Fatal(i, "need btreeDataPage")
564 }
565
566 dp = btreeDataPage(p)
567 n = dp.len()
568 if n < 0 || n > 2*kData {
569 t.Fatal(i, n)
570 }
571
572 if index < 0 || index > n {
573 t.Fatal(index, n)
574 }
575
576 if index == n {
577 ph := dp.next()
578 if i == N {
579 if ph != 0 {
580 t.Fatal(ph)
581 }
582
583 continue
584 }
585
586 index = 0
587 if dp, err = a.Get(p, ph); err != nil {
588 t.Fatal(err)
589 }
590 }
591
592 g, err = dp.key(a, index)
593 if err != nil {
594 t.Fatal(err)
595 }
596
597 expKey = enc8(10 * (i + 1))
598 if !bytes.Equal(g, expKey) {
599 //fmt.Println(root.String(a))
600 t.Fatalf("%d low|% x| g|% x| e|% x|", i, lowKey, g, expKey)
601 }
602
603 g, err = dp.value(a, index)
604 if err != nil {
605 t.Fatal(err)
606 }
607
608 value = enc8(10*(i+1) + 1)
609 if !bytes.Equal(g, value) {
610 t.Fatal(i)
611 }
612
613 }
614 }
615
616 func enc8(n int64) []byte {
617 var b [8]byte
618 h2b(b[:], n)
619 return b[:]
620 }
621
622 func dec8(b []byte) (int64, error) {
623 if len(b) != 0 {
624 return 0, fmt.Errorf("dec8: len != 8 but %d", len(b))
625 }
626
627 return b2h(b), nil
628 }
629
630 func TestbTreeNext(t *testing.T) {
631 N := int64(*testN)
632
633 tree := NewBTree(nil)
634 enum, _, err := tree.seek(enc8(0))
635 if err != nil {
636 t.Fatal(err)
637 }
638
639 if _, _, err = enum.current(); !fileutil.IsEOF(err) {
640 t.Fatal(err)
641 }
642
643 if err = enum.next(); !fileutil.IsEOF(err) {
644 t.Fatal(err)
645 }
646
647 if err = enum.prev(); !fileutil.IsEOF(err) {
648 t.Fatal(err)
649 }
650
651 // Fill
652 for i := int64(1); i <= N; i++ {
653 tree.Set(enc8(10*i), enc8(10*i+1))
654 }
655
656 var eq bool
657
658 enum, eq, err = tree.seek(enc8(0))
659 if err != nil {
660 t.Fatal(err)
661 }
662
663 if eq {
664 t.Fatal(eq)
665 }
666
667 // index: 0
668 if _, _, err = enum.current(); err != nil {
669 t.Fatal(err)
670 }
671
672 if err = enum.next(); N > 1 && err != nil {
673 t.Fatal(err)
674 }
675
676 enum, eq, err = tree.seek(enc8(N * 10))
677 if err != nil {
678 t.Fatal(err)
679 }
680
681 if !eq {
682 t.Fatal(eq)
683 }
684
685 // index: N-1
686 if _, _, err = enum.current(); err != nil {
687 t.Fatal(err)
688 }
689
690 if err = enum.next(); N > 1 && !fileutil.IsEOF(err) {
691 t.Fatal(err)
692 }
693
694 enum, eq, err = tree.seek(enc8(N*10 + 1))
695 if err != nil {
696 t.Fatal(err)
697 }
698
699 if eq {
700 t.Fatal(eq)
701 }
702
703 // index: N
704 if _, _, err = enum.current(); !fileutil.IsEOF(err) {
705 t.Fatal(err)
706 }
707
708 if err = enum.next(); N > 1 && !fileutil.IsEOF(err) {
709 t.Fatal(err)
710 }
711
712 enum, _, err = tree.seek(enc8(0))
713 if err != nil {
714 t.Fatal(err)
715 }
716
717 for i := int64(1); i <= N; i++ {
718 expKey, expValue := enc8(10*i), enc8(10*i+1)
719 k, v, err := enum.current()
720 if err != nil {
721 t.Fatal(err)
722 }
723
724 if !bytes.Equal(k, expKey) {
725 t.Fatal(i)
726 }
727
728 if !bytes.Equal(v, expValue) {
729 t.Fatal(i)
730 }
731
732 switch {
733 case i == N:
734 if err := enum.next(); !fileutil.IsEOF(err) {
735 t.Fatal(err)
736 }
737 default:
738 if err := enum.next(); err != nil {
739 t.Fatal(err)
740 }
741 }
742 }
743 }
744
745 func TestbTreePrev(t *testing.T) {
746 N := int64(*testN)
747
748 tree := NewBTree(nil)
749 enum, _, err := tree.seek(enc8(0))
750 if err != nil {
751 t.Fatal(err)
752 }
753
754 if _, _, err = enum.current(); !fileutil.IsEOF(err) {
755 t.Fatal(err)
756 }
757
758 if err = enum.next(); !fileutil.IsEOF(err) {
759 t.Fatal(err)
760 }
761
762 if err = enum.prev(); !fileutil.IsEOF(err) {
763 t.Fatal(err)
764 }
765
766 // Fill
767 for i := int64(1); i <= N; i++ {
768 tree.Set(enc8(10*i), enc8(10*i+1))
769 }
770
771 var eq bool
772
773 enum, eq, err = tree.seek(enc8(0))
774 if err != nil {
775 t.Fatal(err)
776 }
777
778 if eq {
779 t.Fatal(eq)
780 }
781
782 // index: 0
783 if _, _, err = enum.current(); err != nil {
784 t.Fatal(err)
785 }
786
787 if err = enum.prev(); !fileutil.IsEOF(err) {
788 t.Fatal(err)
789 }
790
791 enum, eq, err = tree.seek(enc8(N * 10))
792 if err != nil {
793 t.Fatal(err)
794 }
795
796 if !eq {
797 t.Fatal(eq)
798 }
799
800 // index: N-1
801 if _, _, err = enum.current(); err != nil {
802 t.Fatal(err)
803 }
804
805 if err = enum.prev(); N > 1 && err != nil {
806 t.Fatal(err)
807 }
808
809 enum, eq, err = tree.seek(enc8(N*10 + 1))
810 if err != nil {
811 t.Fatal(err)
812 }
813
814 if eq {
815 t.Fatal(eq)
816 }
817
818 // index: N
819 if _, _, err = enum.current(); !fileutil.IsEOF(err) {
820 t.Fatal(err)
821 }
822
823 if err = enum.prev(); err != nil {
824 t.Fatal(err)
825 }
826
827 enum, _, err = tree.seek(enc8(N * 10))
828 if err != nil {
829 t.Fatal(err)
830 }
831
832 for i := N; i >= 1; i-- {
833 expKey, expValue := enc8(10*i), enc8(10*i+1)
834 k, v, err := enum.current()
835 if err != nil {
836 t.Fatal(err)
837 }
838
839 if !bytes.Equal(k, expKey) {
840 t.Fatalf("%d k|% x| expK|% x| %s\n", i, k, expKey, tree.root.String(tree.store))
841 }
842
843 if !bytes.Equal(v, expValue) {
844 t.Fatal(i)
845 }
846
847 switch {
848 case i == 1:
849 if err := enum.prev(); !fileutil.IsEOF(err) {
850 t.Fatal(err)
851 }
852 default:
853 if err := enum.prev(); err != nil {
854 t.Fatal(i, err)
855 }
856 }
857 }
858 }
859
860 func TestBTreeClear(t *testing.T) {
861 N := int64(*testN)
862
863 var err error
864 var p []byte
865 for n := int64(0); n <= N; n = n*3/2 + 1 {
866 tree := NewBTree(nil)
867 for i := int64(0); i < n; i++ {
868 k := append(make([]byte, kKV), enc8(10*i+1)...)
869 v := append(make([]byte, kKV+1), enc8(10*i+2)...)
870 if err = tree.Set(k, v); err != nil {
871 t.Fatal(err)
872 }
873 }
874
875 if err = tree.Clear(); err != nil {
876 t.Fatal(err)
877 }
878
879 if g, e := len(tree.store.(*memBTreeStore).m), 1; g != e {
880 t.Fatalf("%v %v %v\n%s", n, g, e, tree.store.(*memBTreeStore).String())
881 }
882
883 if p, err = tree.store.Get(p, 1); err != nil {
884 t.Fatal(err)
885 }
886
887 if g, e := p, zeros[:7]; len(g) != 0 && !bytes.Equal(g, e) {
888 t.Fatalf("|% x| |% x|", g, e)
889 }
890 }
891 }
892
893 func TestBTreeRemove(t *testing.T) {
894 N := int64(*testN)
895
896 for n := int64(0); n <= N; n = n*3/2 + 1 {
897 f := NewMemFiler()
898 store, err := NewAllocator(f, &Options{})
899 if err != nil {
900 t.Fatal(err)
901 }
902
903 sz0, err := f.Size()
904 if err != nil {
905 t.Fatal(err)
906 }
907
908 tree, handle, err := CreateBTree(store, nil)
909 if err != nil {
910 t.Fatal(err)
911 }
912
913 for i := int64(0); i < n; i++ {
914 k := append(make([]byte, kKV), enc8(10*i+1)...)
915 v := append(make([]byte, kKV+1), enc8(10*i+2)...)
916 if err = tree.Set(k, v); err != nil {
917 t.Fatal(err)
918 }
919 }
920
921 if err = RemoveBTree(store, handle); err != nil {
922 t.Fatal(err)
923 }
924
925 sz, err := f.Size()
926 if err != nil {
927 t.Fatal(err)
928 }
929
930 if g, e := sz-sz0, int64(0); g != e {
931 t.Fatal(g, e)
932 }
933 }
934 }
935
936 func collate(a, b []byte) (r int) {
937 da, err := DecodeScalars(a)
938 if err != nil {
939 panic(err)
940 }
941
942 db, err := DecodeScalars(b)
943 if err != nil {
944 panic(err)
945 }
946
947 r, err = Collate(da, db, nil)
948 if err != nil {
949 panic(err)
950 }
951
952 return
953 }
954
955 func TestBTreeCollatingBug(t *testing.T) {
956 tree := NewBTree(collate)
957
958 date, err := EncodeScalars("Date")
959 if err != nil {
960 t.Fatal(err)
961 }
962
963 customer, err := EncodeScalars("Customer")
964 if err != nil {
965 t.Fatal(err)
966 }
967
968 if g, e := collate(customer, date), -1; g != e {
969 t.Fatal(g, e)
970 }
971
972 if g, e := collate(date, customer), 1; g != e {
973 t.Fatal(g, e)
974 }
975
976 err = tree.Set(date, nil)
977 if err != nil {
978 t.Fatal(err)
979 }
980
981 err = tree.Set(customer, nil)
982 if err != nil {
983 t.Fatal(err)
984 }
985
986 var b bytes.Buffer
987 tree.Dump(&b)
988 t.Logf("\n%s", b.String())
989
990 key, _, err := tree.First()
991 if err != nil {
992 t.Fatal(err)
993 }
994
995 if g, e := key, customer; !bytes.Equal(g, e) {
996 t.Fatal(g, e)
997 }
998
999 }
1000
1001 func TestExtract(t *testing.T) { // Test of the exported wrapper only, .extract tested elsewhere
1002 bt := NewBTree(nil)
1003 bt.Set([]byte("a"), []byte("b"))
1004 bt.Set([]byte("c"), []byte("d"))
1005 bt.Set([]byte("e"), []byte("f"))
1006
1007 if v, err := bt.Get(nil, []byte("a")); string(v) != "b" || err != nil {
1008 t.Fatal(v, err)
1009 }
1010
1011 if v, err := bt.Get(nil, []byte("c")); string(v) != "d" || err != nil {
1012 t.Fatal(v, err)
1013 }
1014
1015 if v, err := bt.Get(nil, []byte("e")); string(v) != "f" || err != nil {
1016 t.Fatal(v, err)
1017 }
1018
1019 if v, err := bt.Extract(nil, []byte("c")); string(v) != "d" || err != nil {
1020 t.Fatal(v, err)
1021 }
1022
1023 if v, err := bt.Get(nil, []byte("a")); string(v) != "b" || err != nil {
1024 t.Fatal(v, err)
1025 }
1026
1027 if v, err := bt.Get(nil, []byte("c")); v != nil || err != nil {
1028 t.Fatal(v, err)
1029 }
1030
1031 if v, err := bt.Get(nil, []byte("e")); string(v) != "f" || err != nil {
1032 t.Fatal(v, err)
1033 }
1034 }
1035
1036 func TestFirst(t *testing.T) {
1037 bt := NewBTree(nil)
1038
1039 if k, v, err := bt.First(); k != nil || v != nil || err != nil {
1040 t.Fatal(k, v, err)
1041 }
1042
1043 bt.Set([]byte("a"), []byte("b"))
1044 bt.Set([]byte("c"), []byte("d"))
1045
1046 if k, v, err := bt.First(); string(k) != "a" || string(v) != "b" || err != nil {
1047 t.Fatal(k, v, err)
1048 }
1049
1050 if err := bt.Delete([]byte("a")); err != nil {
1051 t.Fatal(err)
1052 }
1053
1054 if k, v, err := bt.First(); string(k) != "c" || string(v) != "d" || err != nil {
1055 t.Fatal(k, v, err)
1056 }
1057
1058 if err := bt.Delete([]byte("c")); err != nil {
1059 t.Fatal(err)
1060 }
1061
1062 if k, v, err := bt.First(); k != nil || v != nil || err != nil {
1063 t.Fatal(k, v, err)
1064 }
1065 }
1066
1067 func TestLast(t *testing.T) {
1068 bt := NewBTree(nil)
1069
1070 if k, v, err := bt.First(); k != nil || v != nil || err != nil {
1071 t.Fatal(k, v, err)
1072 }
1073
1074 bt.Set([]byte("a"), []byte("b"))
1075 bt.Set([]byte("c"), []byte("d"))
1076
1077 if k, v, err := bt.Last(); string(k) != "c" || string(v) != "d" || err != nil {
1078 t.Fatal(k, v, err)
1079 }
1080
1081 if err := bt.Delete([]byte("c")); err != nil {
1082 t.Fatal(err)
1083 }
1084
1085 if k, v, err := bt.First(); string(k) != "a" || string(v) != "b" || err != nil {
1086 t.Fatal(k, v, err)
1087 }
1088
1089 if err := bt.Delete([]byte("a")); err != nil {
1090 t.Fatal(err)
1091 }
1092
1093 if k, v, err := bt.First(); k != nil || v != nil || err != nil {
1094 t.Fatal(k, v, err)
1095 }
1096 }
1097
1098 func TestseekFirst(t *testing.T) {
1099 bt := NewBTree(nil)
1100
1101 enum, err := bt.seekFirst()
1102 if !fileutil.IsEOF(err) {
1103 t.Fatal(err)
1104 }
1105
1106 bt.Set([]byte("c"), []byte("d"))
1107 enum, err = bt.seekFirst()
1108 if err != nil {
1109 t.Fatal(err)
1110 }
1111
1112 err = enum.prev()
1113 if !fileutil.IsEOF(err) {
1114 t.Fatal(err)
1115 }
1116
1117 err = enum.next()
1118 if !fileutil.IsEOF(err) {
1119 t.Fatal(err)
1120 }
1121
1122 k, v, err := enum.current()
1123 if err != nil {
1124 t.Fatal(err)
1125 }
1126
1127 if string(k) != "c" || string(v) != "d" {
1128 t.Fatal(k, v)
1129 }
1130
1131 bt.Set([]byte("a"), []byte("b"))
1132 enum, err = bt.seekFirst()
1133 if err != nil {
1134 t.Fatal(err)
1135 }
1136
1137 err = enum.prev()
1138 if !fileutil.IsEOF(err) {
1139 t.Fatal(err)
1140 }
1141
1142 k, v, err = enum.current()
1143 if err != nil {
1144 t.Fatal(err)
1145 }
1146
1147 if string(k) != "a" || string(v) != "b" {
1148 t.Fatal(k, v)
1149 }
1150
1151 err = enum.next()
1152 if err != nil {
1153 t.Fatal(err)
1154 }
1155
1156 k, v, err = enum.current()
1157 if err != nil {
1158 t.Fatal(err)
1159 }
1160
1161 if string(k) != "c" || string(v) != "d" {
1162 t.Fatal(k, v)
1163 }
1164 }
1165
1166 func TestseekLast(t *testing.T) {
1167 bt := NewBTree(nil)
1168
1169 enum, err := bt.seekFirst()
1170 if !fileutil.IsEOF(err) {
1171 t.Fatal(err)
1172 }
1173
1174 bt.Set([]byte("a"), []byte("b"))
1175 enum, err = bt.seekFirst()
1176 if err != nil {
1177 t.Fatal(err)
1178 }
1179
1180 err = enum.prev()
1181 if !fileutil.IsEOF(err) {
1182 t.Fatal(err)
1183 }
1184
1185 err = enum.next()
1186 if !fileutil.IsEOF(err) {
1187 t.Fatal(err)
1188 }
1189
1190 k, v, err := enum.current()
1191 if err != nil {
1192 t.Fatal(err)
1193 }
1194
1195 if string(k) != "a" || string(v) != "b" {
1196 t.Fatal(k, v)
1197 }
1198
1199 bt.Set([]byte("c"), []byte("d"))
1200 enum, err = bt.seekLast()
1201 if err != nil {
1202 t.Fatal(err)
1203 }
1204
1205 err = enum.next()
1206 if !fileutil.IsEOF(err) {
1207 t.Fatal(err)
1208 }
1209
1210 k, v, err = enum.current()
1211 if err != nil {
1212 t.Fatal(err)
1213 }
1214
1215 if string(k) != "c" || string(v) != "d" {
1216 t.Fatal(k, v)
1217 }
1218
1219 err = enum.prev()
1220 if err != nil {
1221 t.Fatal(err)
1222 }
1223
1224 k, v, err = enum.current()
1225 if err != nil {
1226 t.Fatal(err)
1227 }
1228
1229 if string(k) != "a" || string(v) != "b" {
1230 t.Fatal(k, v)
1231 }
1232 }
1233
1234 func TestDeleteAny(t *testing.T) {
1235 const N = 1e4
1236 rng := rand.New(rand.NewSource(42))
1237 ref := map[uint32]bool{}
1238 tr := NewBTree(nil)
1239 data := []byte{42}
1240 var key [4]byte
1241 for i := 0; i < N; i++ {
1242 k := uint32(rng.Int())
1243 binary.LittleEndian.PutUint32(key[:], k)
1244 if err := tr.Set(key[:], data); err != nil {
1245 t.Fatal(err)
1246 }
1247
1248 ref[k] = true
1249 }
1250
1251 for i := len(ref); i != 0; i-- {
1252 empty, err := tr.DeleteAny()
1253 if err != nil {
1254 t.Fatal(err)
1255 }
1256
1257 if empty && i != 1 {
1258 t.Fatal(i)
1259 }
1260 }
1261 }
1262
1263 func benchmarkBTreeSetFiler(b *testing.B, f Filer, sz int) {
1264 if err := f.BeginUpdate(); err != nil {
1265 b.Error(err)
1266 return
1267 }
1268
1269 a, err := NewAllocator(f, &Options{})
1270 if err != nil {
1271 b.Error(err)
1272 return
1273 }
1274
1275 tr, _, err := CreateBTree(a, nil)
1276 if err != nil {
1277 f.EndUpdate()
1278 b.Error(err)
1279 return
1280 }
1281
1282 if err = f.EndUpdate(); err != nil {
1283 b.Error(err)
1284 return
1285 }
1286
1287 keys := make([][8]byte, b.N)
1288 for i := range keys {
1289 binary.BigEndian.PutUint64(keys[i][:], uint64(i))
1290 }
1291 v := make([]byte, sz)
1292 runtime.GC()
1293 b.ResetTimer()
1294 for _, k := range keys {
1295 if err = f.BeginUpdate(); err != nil {
1296 b.Error(err)
1297 return
1298 }
1299
1300 if err := tr.Set(k[:], v); err != nil {
1301 f.EndUpdate()
1302 b.Error(err)
1303 return
1304 }
1305
1306 if err = f.EndUpdate(); err != nil {
1307 b.Error(err)
1308 return
1309 }
1310 }
1311 }
1312
1313 func benchmarkBTreeSetMemFiler(b *testing.B, sz int) {
1314 f := NewMemFiler()
1315 benchmarkBTreeSetFiler(b, f, sz)
1316 }
1317
1318 func BenchmarkBTreeSetMemFiler0(b *testing.B) {
1319 benchmarkBTreeSetMemFiler(b, 0)
1320 }
1321
1322 func BenchmarkBTreeSetMemFiler1e1(b *testing.B) {
1323 benchmarkBTreeSetMemFiler(b, 1e1)
1324 }
1325
1326 func BenchmarkBTreeSetMemFiler1e2(b *testing.B) {
1327 benchmarkBTreeSetMemFiler(b, 1e2)
1328 }
1329
1330 func BenchmarkBTreeSetMemFiler1e3(b *testing.B) {
1331 benchmarkBTreeSetMemFiler(b, 1e3)
1332 }
1333
1334 func benchmarkBTreeSetSimpleFileFiler(b *testing.B, sz int) {
1335 dir, testDbName := temp()
1336 defer os.RemoveAll(dir)
1337
1338 f, err := os.OpenFile(testDbName, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1339 if err != nil {
1340 b.Fatal(err)
1341 }
1342
1343 defer f.Close()
1344
1345 benchmarkBTreeSetFiler(b, NewSimpleFileFiler(f), sz)
1346 }
1347
1348 func BenchmarkBTreeSetSimpleFileFiler0(b *testing.B) {
1349 benchmarkBTreeSetSimpleFileFiler(b, 0)
1350 }
1351
1352 func BenchmarkBTreeSetSimpleFileFiler1e1(b *testing.B) {
1353 benchmarkBTreeSetSimpleFileFiler(b, 1e1)
1354 }
1355
1356 func BenchmarkBTreeSetSimpleFileFiler1e2(b *testing.B) {
1357 benchmarkBTreeSetSimpleFileFiler(b, 1e2)
1358 }
1359
1360 func BenchmarkBTreeSetSimpleFileFiler1e3(b *testing.B) {
1361 benchmarkBTreeSetSimpleFileFiler(b, 1e3)
1362 }
1363
1364 func benchmarkBTreeSetRollbackFiler(b *testing.B, sz int) {
1365 dir, testDbName := temp()
1366 defer os.RemoveAll(dir)
1367
1368 f, err := os.OpenFile(testDbName, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1369 if err != nil {
1370 b.Fatal(err)
1371 }
1372
1373 defer f.Close()
1374
1375 g := NewSimpleFileFiler(f)
1376 var filer *RollbackFiler
1377 if filer, err = NewRollbackFiler(
1378 g,
1379 func(sz int64) error {
1380 if err = g.Truncate(sz); err != nil {
1381 return err
1382 }
1383
1384 return g.Sync()
1385 },
1386 g,
1387 ); err != nil {
1388 b.Error(err)
1389 return
1390 }
1391
1392 benchmarkBTreeSetFiler(b, filer, sz)
1393 }
1394
1395 func BenchmarkBTreeSetRollbackFiler0(b *testing.B) {
1396 benchmarkBTreeSetRollbackFiler(b, 0)
1397 }
1398
1399 func BenchmarkBTreeSetRollbackFiler1e1(b *testing.B) {
1400 benchmarkBTreeSetRollbackFiler(b, 1e1)
1401 }
1402
1403 func BenchmarkBTreeSetRollbackFiler1e2(b *testing.B) {
1404 benchmarkBTreeSetRollbackFiler(b, 1e2)
1405 }
1406
1407 func BenchmarkBTreeSetRollbackFiler1e3(b *testing.B) {
1408 benchmarkBTreeSetRollbackFiler(b, 1e3)
1409 }
1410
1411 func benchmarkBTreeSetACIDFiler(b *testing.B, sz int) {
1412 dir, testDbName := temp()
1413 defer os.RemoveAll(dir)
1414
1415 f, err := os.OpenFile(testDbName, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1416 if err != nil {
1417 b.Fatal(err)
1418 }
1419
1420 defer f.Close()
1421
1422 wal, err := os.OpenFile(testDbName+".wal", os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1423 if err != nil {
1424 b.Fatal(err)
1425 }
1426
1427 defer wal.Close()
1428
1429 filer, err := NewACIDFiler(NewSimpleFileFiler(f), wal)
1430 if err != nil {
1431 b.Error(err)
1432 return
1433 }
1434
1435 benchmarkBTreeSetFiler(b, filer, sz)
1436 }
1437
1438 func BenchmarkBTreeSetACIDFiler0(b *testing.B) {
1439 benchmarkBTreeSetACIDFiler(b, 0)
1440 }
1441
1442 func BenchmarkBTreeSetACIDFiler1e1(b *testing.B) {
1443 benchmarkBTreeSetACIDFiler(b, 1e1)
1444 }
1445
1446 func BenchmarkBTreeSetACIDFiler1e2(b *testing.B) {
1447 benchmarkBTreeSetACIDFiler(b, 1e2)
1448 }
1449
1450 func BenchmarkBTreeSetACIDFiler1e3(b *testing.B) {
1451 benchmarkBTreeSetACIDFiler(b, 1e3)
1452 }
1453
1454 func testbTreeEnumeratorInvalidating(t *testing.T, mutate func(b *BTree) error) {
1455 b := NewBTree(nil)
1456 if err := b.Set([]byte{1}, []byte{2}); err != nil {
1457 t.Fatal(err)
1458 }
1459
1460 if err := b.Set([]byte{3}, []byte{4}); err != nil {
1461 t.Fatal(err)
1462 }
1463
1464 e, err := b.seekFirst()
1465 if err != nil {
1466 t.Fatal(err)
1467 }
1468
1469 if _, _, err = e.current(); err != nil {
1470 t.Fatal(err)
1471 }
1472
1473 if err = e.next(); err != nil {
1474 t.Fatal(err)
1475 }
1476
1477 if err = e.prev(); err != nil {
1478 t.Fatal(err)
1479 }
1480
1481 if err = mutate(b); err != nil {
1482 t.Fatal(err)
1483 }
1484
1485 if _, _, err = e.current(); err == nil {
1486 t.Fatal(err)
1487 }
1488
1489 if _, ok := err.(*ErrINVAL); !ok {
1490 t.Fatalf("%T", err)
1491 }
1492
1493 err = e.next()
1494 if err == nil {
1495 t.Fatal(err)
1496 }
1497
1498 if _, ok := err.(*ErrINVAL); !ok {
1499 t.Fatalf("%T", err)
1500 }
1501
1502 err = e.prev()
1503 if err == nil {
1504 t.Fatal(err)
1505 }
1506
1507 if _, ok := err.(*ErrINVAL); !ok {
1508 t.Fatalf("%T", err)
1509 }
1510
1511 }
1512
1513 func TestBTreeEnumeratorInvalidating(t *testing.T) {
1514 testbTreeEnumeratorInvalidating(t, func(b *BTree) error { return b.Clear() })
1515 testbTreeEnumeratorInvalidating(t, func(b *BTree) error { return b.Delete([]byte{1}) })
1516 testbTreeEnumeratorInvalidating(t, func(b *BTree) error { _, err := b.DeleteAny(); return err })
1517 testbTreeEnumeratorInvalidating(t, func(b *BTree) error { _, err := b.Extract(nil, []byte{1}); return err })
1518 testbTreeEnumeratorInvalidating(t, func(b *BTree) error {
1519 _, _, err := b.Put(
1520 nil,
1521 []byte{1},
1522 func(k, o []byte) ([]byte, bool, error) { return nil, false, nil },
1523 )
1524 return err
1525 })
1526 testbTreeEnumeratorInvalidating(t, func(b *BTree) error { return b.Set([]byte{4}, []byte{5}) })
1527 }
1528
1529 func n2b(n int) []byte {
1530 var b [8]byte
1531 binary.BigEndian.PutUint64(b[:], uint64(n))
1532 return b[:]
1533 }
1534
1535 func b2n(b []byte) int {
1536 if len(b) != 8 {
1537 return mathutil.MinInt
1538 }
1539
1540 return int(binary.BigEndian.Uint64(b))
1541 }
1542
1543 func TestBTreeSeekNext(t *testing.T) {
1544 // seeking within 3 keys: 10, 20, 30
1545 table := []struct {
1546 k int
1547 hit bool
1548 keys []int
1549 }{
1550 {5, false, []int{10, 20, 30}},
1551 {10, true, []int{10, 20, 30}},
1552 {15, false, []int{20, 30}},
1553 {20, true, []int{20, 30}},
1554 {25, false, []int{30}},
1555 {30, true, []int{30}},
1556 {35, false, []int{}},
1557 }
1558
1559 for i, test := range table {
1560 up := test.keys
1561 db := NewBTree(nil)
1562
1563 if err := db.Set(n2b(10), n2b(100)); err != nil {
1564 t.Fatal(i, err)
1565 }
1566
1567 if err := db.Set(n2b(20), n2b(200)); err != nil {
1568 t.Fatal(i, err)
1569 }
1570
1571 if err := db.Set(n2b(30), n2b(300)); err != nil {
1572 t.Fatal(i, err)
1573 }
1574
1575 for brokenSerial := 0; brokenSerial < 16; brokenSerial++ {
1576 en, hit, err := db.Seek(n2b(test.k))
1577 if err != nil {
1578 t.Fatal(err)
1579 }
1580
1581 if g, e := hit, test.hit; g != e {
1582 t.Fatal(i, g, e)
1583 }
1584
1585 j := 0
1586 for {
1587 if brokenSerial&(1<<uint(j)) != 0 {
1588 if err := db.Set(n2b(20), n2b(200)); err != nil {
1589 t.Fatal(i, err)
1590 }
1591 }
1592
1593 k, v, err := en.Next()
1594 if err != nil {
1595 if !fileutil.IsEOF(err) {
1596 t.Fatal(i, err)
1597 }
1598
1599 break
1600 }
1601
1602 if g, e := len(k), 8; g != e {
1603 t.Fatal(i, g, e)
1604 }
1605
1606 if j >= len(up) {
1607 t.Fatal(i, j, brokenSerial)
1608 }
1609
1610 if g, e := b2n(k), up[j]; g != e {
1611 t.Fatal(i, j, brokenSerial, g, e)
1612 }
1613
1614 if g, e := len(v), 8; g != e {
1615 t.Fatal(i, g, e)
1616 }
1617
1618 if g, e := b2n(v), 10*up[j]; g != e {
1619 t.Fatal(i, g, e)
1620 }
1621
1622 j++
1623
1624 }
1625
1626 if g, e := j, len(up); g != e {
1627 t.Fatal(i, j, g, e)
1628 }
1629 }
1630
1631 }
1632 }
1633
1634 func TestBTreeSeekPrev(t *testing.T) {
1635 // seeking within 3 keys: 10, 20, 30
1636 table := []struct {
1637 k int
1638 hit bool
1639 keys []int
1640 }{
1641 {5, false, []int{10}},
1642 {10, true, []int{10}},
1643 {15, false, []int{20, 10}},
1644 {20, true, []int{20, 10}},
1645 {25, false, []int{30, 20, 10}},
1646 {30, true, []int{30, 20, 10}},
1647 {35, false, []int{}},
1648 }
1649
1650 for i, test := range table {
1651 down := test.keys
1652 db := NewBTree(nil)
1653 if err := db.Set(n2b(10), n2b(100)); err != nil {
1654 t.Fatal(i, err)
1655 }
1656
1657 if err := db.Set(n2b(20), n2b(200)); err != nil {
1658 t.Fatal(i, err)
1659 }
1660
1661 if err := db.Set(n2b(30), n2b(300)); err != nil {
1662 t.Fatal(i, err)
1663 }
1664
1665 for brokenSerial := 0; brokenSerial < 16; brokenSerial++ {
1666 en, hit, err := db.Seek(n2b(test.k))
1667 if err != nil {
1668 t.Fatal(err)
1669 }
1670
1671 if g, e := hit, test.hit; g != e {
1672 t.Fatal(i, g, e)
1673 }
1674
1675 j := 0
1676 for {
1677 if brokenSerial&(1<<uint(j)) != 0 {
1678 if err := db.Set(n2b(20), n2b(200)); err != nil {
1679 t.Fatal(i, err)
1680 }
1681 }
1682
1683 k, v, err := en.Prev()
1684 if err != nil {
1685 if !fileutil.IsEOF(err) {
1686 t.Fatal(i, err)
1687 }
1688
1689 break
1690 }
1691
1692 if g, e := len(k), 8; g != e {
1693 t.Fatal(i, g, e)
1694 }
1695
1696 if j >= len(down) {
1697 t.Fatal(i, j, brokenSerial)
1698 }
1699
1700 if g, e := b2n(k), down[j]; g != e {
1701 t.Fatal(i, j, brokenSerial, g, e)
1702 }
1703
1704 if g, e := len(v), 8; g != e {
1705 t.Fatal(i, g, e)
1706 }
1707
1708 if g, e := b2n(v), 10*down[j]; g != e {
1709 t.Fatal(i, g, e)
1710 }
1711
1712 j++
1713
1714 }
1715
1716 if g, e := j, len(down); g != e {
1717 t.Fatal(i, j, g, e)
1718 }
1719 }
1720
1721 }
1722 }
1723
1724 func TestBTreeSeekFirst(t *testing.T) {
1725 db := NewBTree(nil)
1726 en, err := db.SeekFirst()
1727 if err == nil {
1728 t.Fatal(err)
1729 }
1730
1731 if err := db.Set(n2b(100), n2b(1000)); err != nil {
1732 t.Fatal(err)
1733 }
1734
1735 if en, err = db.SeekFirst(); err != nil {
1736 t.Fatal(err)
1737 }
1738
1739 k, v, err := en.Next()
1740 if err != nil {
1741 t.Fatal(err)
1742 }
1743
1744 if g, e := b2n(k), 100; g != e {
1745 t.Fatal(g, e)
1746 }
1747
1748 if g, e := b2n(v), 1000; g != e {
1749 t.Fatal(g, e)
1750 }
1751
1752 if err := db.Set(n2b(110), n2b(1100)); err != nil {
1753 t.Fatal(err)
1754 }
1755
1756 if en, err = db.SeekFirst(); err != nil {
1757 t.Fatal(err)
1758 }
1759
1760 if k, v, err = en.Next(); err != nil {
1761 t.Fatal(err)
1762 }
1763
1764 if g, e := b2n(k), 100; g != e {
1765 t.Fatal(g, e)
1766 }
1767
1768 if g, e := b2n(v), 1000; g != e {
1769 t.Fatal(g, e)
1770 }
1771
1772 if err := db.Set(n2b(90), n2b(900)); err != nil {
1773 t.Fatal(err)
1774 }
1775
1776 if en, err = db.SeekFirst(); err != nil {
1777 t.Fatal(err)
1778 }
1779
1780 if k, v, err = en.Next(); err != nil {
1781 t.Fatal(err)
1782 }
1783
1784 if g, e := b2n(k), 90; g != e {
1785 t.Fatal(g, e)
1786 }
1787
1788 if g, e := b2n(v), 900; g != e {
1789 t.Fatal(g, e)
1790 }
1791
1792 }
1793
1794 func TestBTreeSeekLast(t *testing.T) {
1795 db := NewBTree(nil)
1796 en, err := db.SeekLast()
1797 if err == nil {
1798 t.Fatal(err)
1799 }
1800
1801 if err := db.Set(n2b(100), n2b(1000)); err != nil {
1802 t.Fatal(err)
1803 }
1804
1805 if en, err = db.SeekLast(); err != nil {
1806 t.Fatal(err)
1807 }
1808
1809 k, v, err := en.Next()
1810 if err != nil {
1811 t.Fatal(err)
1812 }
1813
1814 if g, e := b2n(k), 100; g != e {
1815 t.Fatal(g, e)
1816 }
1817
1818 if g, e := b2n(v), 1000; g != e {
1819 t.Fatal(g, e)
1820 }
1821
1822 if err := db.Set(n2b(90), n2b(900)); err != nil {
1823 t.Fatal(err)
1824 }
1825
1826 if en, err = db.SeekLast(); err != nil {
1827 t.Fatal(err)
1828 }
1829
1830 if k, v, err = en.Next(); err != nil {
1831 t.Fatal(err)
1832 }
1833
1834 if g, e := b2n(k), 100; g != e {
1835 t.Fatal(g, e)
1836 }
1837
1838 if g, e := b2n(v), 1000; g != e {
1839 t.Fatal(g, e)
1840 }
1841
1842 if err := db.Set(n2b(110), n2b(1100)); err != nil {
1843 t.Fatal(err)
1844 }
1845
1846 if en, err = db.SeekLast(); err != nil {
1847 t.Fatal(err)
1848 }
1849
1850 if k, v, err = en.Next(); err != nil {
1851 t.Fatal(err)
1852 }
1853
1854 if g, e := b2n(k), 110; g != e {
1855 t.Fatal(g, e)
1856 }
1857
1858 if g, e := b2n(v), 1100; g != e {
1859 t.Fatal(g, e)
1860 }
1861
1862 }
1863
1864 // https://code.google.com/p/camlistore/issues/detail?id=216
1865 func TestBug216(t *testing.T) {
1866 const S = 2*kKV + 2 // 2*kKV+1 ok
1867 const N = 300000
1868 rng, err := mathutil.NewFC32(math.MinInt32, math.MaxInt32, true)
1869 if err != nil {
1870 t.Fatal(err)
1871 }
1872 k := make([]byte, S/2)
1873 v := make([]byte, S-S/2)
1874 tr := NewBTree(nil)
1875 for i := 0; i < N; i++ {
1876 for i := range k {
1877 k[i] = byte(rng.Next())
1878 }
1879 for i := range v {
1880 v[i] = byte(rng.Next())
1881 }
1882
1883 if err := tr.Set(h2b(k, int64(i)), h2b(v, int64(i))); err != nil {
1884 t.Fatal(i, err)
1885 }
1886
1887 if (i+1)%10000 == 0 {
1888 //dbg("%v", i+1)
1889 }
1890 }
1891 }
1892
1893 func testKVBug27(t *testing.T, keys []string) {
1894 v := []byte("doesn't matter")
1895 tr := NewBTree(bytes.Compare)
1896
1897 exp := 0
1898 for _, k := range keys {
1899 k := []byte(k)
1900 if k[0] >= 0x10 {
1901 exp++
1902 }
1903 if err := tr.Set(k, v); err != nil {
1904 t.Fatal(len(keys), err)
1905 }
1906 }
1907
1908 k := [20]byte{0x10}
1909 e, _, err := tr.Seek(k[:])
1910 if err != nil {
1911 t.Fatal(err)
1912 }
1913
1914 got := 0
1915 for {
1916 if _, _, err = e.Next(); err != nil {
1917 if err == io.EOF {
1918 break
1919 }
1920
1921 t.Fatal(err)
1922 }
1923 got++
1924 }
1925 if got != exp {
1926 t.Errorf("keys %v, got %v, exp %v: FAIL", len(keys), got, exp)
1927 return
1928 }
1929
1930 t.Logf("keys %v, got %v, exp %v", len(keys), got, exp)
1931 }
1932
1933 func TestKVBug27(t *testing.T) { // https://github.com/cznic/kv/issues/27
1934 f, err := ioutil.ReadFile("testdata/fortunes.txt")
1935 if err != nil {
1936 t.Fatal(err)
1937 }
1938
1939 keys := strings.Split(string(f), "\n")
1940 for i, v := range keys {
1941 h := sha1.Sum([]byte(v))
1942 keys[i] = string(h[:])
1943 }
1944 sort.Strings(keys)
1945 testKVBug27(t, keys[:795])
1946 testKVBug27(t, keys[:796])
1947 testKVBug27(t, keys[:797])
1948 }
1949
1950 func TestGetEmpty(t *testing.T) {
1951 tr := NewBTree(nil)
1952 empty := []byte("empty")
1953 missing := []byte("missing")
1954 err := tr.Set(empty, nil)
1955 if err != nil {
1956 t.Fatal(err)
1957 }
1958 for _, buf := range [][]byte{nil, {}} {
1959 data, err := tr.Get(buf, missing)
1960 if err != nil {
1961 t.Fatal(err)
1962 }
1963 if data != nil {
1964 t.Fatalf("missing key returned non-nil data")
1965 }
1966 }
1967 for _, buf := range [][]byte{nil, {}} {
1968 data, err := tr.Get(buf, empty)
1969 if err != nil {
1970 t.Fatal(err)
1971 }
1972 if data == nil || len(data) != 0 {
1973 t.Fatalf("empty key returned nil or non-empty data")
1974 }
1975 }
1976 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 // Some errors returned by this package.
5 //
6 // Note that this package can return more errors than declared here, for
7 // example io.EOF from Filer.ReadAt().
8
9 package lldb
10
11 import (
12 "fmt"
13 )
14
15 // ErrDecodeScalars is possibly returned from DecodeScalars
16 type ErrDecodeScalars struct {
17 B []byte // Data being decoded
18 I int // offending offset
19 }
20
21 // Error implements the built in error type.
22 func (e *ErrDecodeScalars) Error() string {
23 return fmt.Sprintf("DecodeScalars: corrupted data @ %d/%d", e.I, len(e.B))
24 }
25
26 // ErrINVAL reports invalid values passed as parameters, for example negative
27 // offsets where only non-negative ones are allowed or read from the DB.
28 type ErrINVAL struct {
29 Src string
30 Val interface{}
31 }
32
33 // Error implements the built in error type.
34 func (e *ErrINVAL) Error() string {
35 return fmt.Sprintf("%s: %+v", e.Src, e.Val)
36 }
37
38 // ErrPERM is for example reported when a Filer is closed while BeginUpdate(s)
39 // are not balanced with EndUpdate(s)/Rollback(s) or when EndUpdate or Rollback
40 // is invoked which is not paired with a BeginUpdate.
41 type ErrPERM struct {
42 Src string
43 }
44
45 // Error implements the built in error type.
46 func (e *ErrPERM) Error() string {
47 return fmt.Sprintf("%s: Operation not permitted", string(e.Src))
48 }
49
50 // ErrTag represents an ErrILSEQ kind.
51 type ErrType int
52
53 // ErrILSEQ types
54 const (
55 ErrOther ErrType = iota
56
57 ErrAdjacentFree // Adjacent free blocks (.Off and .Arg)
58 ErrDecompress // Used compressed block: corrupted compression
59 ErrExpFreeTag // Expected a free block tag, got .Arg
60 ErrExpUsedTag // Expected a used block tag, got .Arg
61 ErrFLT // Free block is invalid or referenced multiple times
62 ErrFLTLoad // FLT truncated to .Off, need size >= .Arg
63 ErrFLTSize // Free block size (.Arg) doesn't belong to its list min size: .Arg2
64 ErrFileSize // File .Name size (.Arg) != 0 (mod 16)
65 ErrFreeChaining // Free block, .prev.next doesn't point back to this block
66 ErrFreeTailBlock // Last block is free
67 ErrHead // Head of a free block list has non zero Prev (.Arg)
68 ErrInvalidRelocTarget // Reloc doesn't target (.Arg) a short or long used block
69 ErrInvalidWAL // Corrupted write ahead log. .Name: file name, .More: more
70 ErrLongFreeBlkTooLong // Long free block spans beyond EOF, size .Arg
71 ErrLongFreeBlkTooShort // Long free block must have at least 2 atoms, got only .Arg
72 ErrLongFreeNextBeyondEOF // Long free block .Next (.Arg) spans beyond EOF
73 ErrLongFreePrevBeyondEOF // Long free block .Prev (.Arg) spans beyond EOF
74 ErrLongFreeTailTag // Expected a long free block tail tag, got .Arg
75 ErrLostFreeBlock // Free block is not in any FLT list
76 ErrNullReloc // Used reloc block with nil target
77 ErrRelocBeyondEOF // Used reloc points (.Arg) beyond EOF
78 ErrShortFreeTailTag // Expected a short free block tail tag, got .Arg
79 ErrSmall // Request for a free block (.Arg) returned a too small one (.Arg2) at .Off
80 ErrTailTag // Block at .Off has invalid tail CC (compression code) tag, got .Arg
81 ErrUnexpReloc // Unexpected reloc block referred to from reloc block .Arg
82 ErrVerifyPadding // Used block has nonzero padding
83 ErrVerifyTailSize // Long free block size .Arg but tail size .Arg2
84 ErrVerifyUsedSpan // Used block size (.Arg) spans beyond EOF
85 )
86
87 // ErrILSEQ reports a corrupted file format. Details in fields according to Type.
88 type ErrILSEQ struct {
89 Type ErrType
90 Off int64
91 Arg int64
92 Arg2 int64
93 Arg3 int64
94 Name string
95 More interface{}
96 }
97
98 // Error implements the built in error type.
99 func (e *ErrILSEQ) Error() string {
100 switch e.Type {
101 case ErrAdjacentFree:
102 return fmt.Sprintf("Adjacent free blocks at offset %#x and %#x", e.Off, e.Arg)
103 case ErrDecompress:
104 return fmt.Sprintf("Compressed block at offset %#x: Corrupted compressed content", e.Off)
105 case ErrExpFreeTag:
106 return fmt.Sprintf("Block at offset %#x: Expected a free block tag, got %#2x", e.Off, e.Arg)
107 case ErrExpUsedTag:
108 return fmt.Sprintf("Block at ofset %#x: Expected a used block tag, got %#2x", e.Off, e.Arg)
109 case ErrFLT:
110 return fmt.Sprintf("Free block at offset %#x is invalid or referenced multiple times", e.Off)
111 case ErrFLTLoad:
112 return fmt.Sprintf("FLT truncated to size %d, expected at least %d", e.Off, e.Arg)
113 case ErrFLTSize:
114 return fmt.Sprintf("Free block at offset %#x has size (%#x) should be at least (%#x)", e.Off, e.Arg, e.Arg2)
115 case ErrFileSize:
116 return fmt.Sprintf("File %q size (%#x) != 0 (mod 16)", e.Name, e.Arg)
117 case ErrFreeChaining:
118 return fmt.Sprintf("Free block at offset %#x: .prev.next doesn point back here.", e.Off)
119 case ErrFreeTailBlock:
120 return fmt.Sprintf("Free block at offset %#x: Cannot be last file block", e.Off)
121 case ErrHead:
122 return fmt.Sprintf("Block at offset %#x: Head of free block list has non zero .prev %#x", e.Off, e.Arg)
123 case ErrInvalidRelocTarget:
124 return fmt.Sprintf("Used reloc block at offset %#x: Target (%#x) is not a short or long used block", e.Off, e.Arg)
125 case ErrInvalidWAL:
126 return fmt.Sprintf("Corrupted write ahead log file: %q %v", e.Name, e.More)
127 case ErrLongFreeBlkTooLong:
128 return fmt.Sprintf("Long free block at offset %#x: Size (%#x) beyond EOF", e.Off, e.Arg)
129 case ErrLongFreeBlkTooShort:
130 return fmt.Sprintf("Long free block at offset %#x: Size (%#x) too small", e.Off, e.Arg)
131 case ErrLongFreeNextBeyondEOF:
132 return fmt.Sprintf("Long free block at offset %#x: Next (%#x) points beyond EOF", e.Off, e.Arg)
133 case ErrLongFreePrevBeyondEOF:
134 return fmt.Sprintf("Long free block at offset %#x: Prev (%#x) points beyond EOF", e.Off, e.Arg)
135 case ErrLongFreeTailTag:
136 return fmt.Sprintf("Block at offset %#x: Expected long free tail tag, got %#2x", e.Off, e.Arg)
137 case ErrLostFreeBlock:
138 return fmt.Sprintf("Free block at offset %#x: not in any FLT list", e.Off)
139 case ErrNullReloc:
140 return fmt.Sprintf("Used reloc block at offset %#x: Nil target", e.Off)
141 case ErrRelocBeyondEOF:
142 return fmt.Sprintf("Used reloc block at offset %#x: Link (%#x) points beyond EOF", e.Off, e.Arg)
143 case ErrShortFreeTailTag:
144 return fmt.Sprintf("Block at offset %#x: Expected short free tail tag, got %#2x", e.Off, e.Arg)
145 case ErrSmall:
146 return fmt.Sprintf("Request for of free block of size %d returned a too small (%d) one at offset %#x", e.Arg, e.Arg2, e.Off)
147 case ErrTailTag:
148 return fmt.Sprintf("Block at offset %#x: Invalid tail CC tag, got %#2x", e.Off, e.Arg)
149 case ErrUnexpReloc:
150 return fmt.Sprintf("Block at offset %#x: Unexpected reloc block. Referred to from reloc block at offset %#x", e.Off, e.Arg)
151 case ErrVerifyPadding:
152 return fmt.Sprintf("Used block at offset %#x: Nonzero padding", e.Off)
153 case ErrVerifyTailSize:
154 return fmt.Sprintf("Long free block at offset %#x: Size %#x, but tail size %#x", e.Off, e.Arg, e.Arg2)
155 case ErrVerifyUsedSpan:
156 return fmt.Sprintf("Used block at offset %#x: Size %#x spans beyond EOF", e.Off, e.Arg)
157 }
158
159 more := ""
160 if e.More != nil {
161 more = fmt.Sprintf(", %v", e.More)
162 }
163 off := ""
164 if e.Off != 0 {
165 off = fmt.Sprintf(", off: %#x", e.Off)
166 }
167
168 return fmt.Sprintf("Error%s%s", off, more)
169 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 // The storage space management.
5
6 package lldb
7
8 import (
9 "bytes"
10 "errors"
11 "fmt"
12 "io"
13 "sort"
14 "strings"
15 "sync"
16
17 "github.com/cznic/bufs"
18 "github.com/cznic/mathutil"
19 "github.com/cznic/zappy"
20 )
21
22 const (
23 maxBuf = maxRq + 20 // bufs,Buffers.Alloc
24 )
25
26 // Options are passed to the NewAllocator to amend some configuration. The
27 // compatibility promise is the same as of struct types in the Go standard
28 // library - introducing changes can be made only by adding new exported
29 // fields, which is backward compatible as long as client code uses field names
30 // to assign values of imported struct types literals.
31 //
32 // NOTE: No options are currently defined.
33 type Options struct{}
34
35 // AllocStats record statistics about a Filer. It can be optionally filled by
36 // Allocator.Verify, if successful.
37 type AllocStats struct {
38 Handles int64 // total valid handles in use
39 Compression int64 // number of compressed blocks
40 TotalAtoms int64 // total number of atoms == AllocAtoms + FreeAtoms
41 AllocBytes int64 // bytes allocated (after decompression, if/where used)
42 AllocAtoms int64 // atoms allocated/used, including relocation atoms
43 Relocations int64 // number of relocated used blocks
44 FreeAtoms int64 // atoms unused
45 AllocMap map[int64]int64 // allocated block size in atoms -> count of such blocks
46 FreeMap map[int64]int64 // free block size in atoms -> count of such blocks
47 }
48
49 /*
50
51 Allocator implements "raw" storage space management (allocation and
52 deallocation) for a low level of a DB engine. The storage is an abstraction
53 provided by a Filer.
54
55 The terms MUST or MUST NOT, if/where used in the documentation of Allocator,
56 written in all caps as seen here, are a requirement for any possible
57 alternative implementations aiming for compatibility with this one.
58
59 Filer file
60
61 A Filer file, or simply 'file', is a linear, contiguous sequence of blocks.
62 Blocks may be either free (currently unused) or allocated (currently used).
63 Some blocks may eventually become virtual in a sense as they may not be
64 realized in the storage (sparse files).
65
66 Free Lists Table
67
68 File starts with a FLT. This table records heads of 14 doubly linked free
69 lists. The zero based index (I) vs minimal size of free blocks in that list,
70 except the last one which registers free blocks of size 4112+ atoms:
71
72 MinSize == 2^I
73
74 For example 0 -> 1, 1 -> 2, ... 12 -> 4096.
75
76 Each entry in the FLT is 8 bytes in netwtork order, MSB MUST be zero, ie. the
77 slot value is effectively only 7 bytes. The value is the handle of the head of
78 the respective doubly linked free list. The FLT size is 14*8 == 112(0x70)
79 bytes. If the free blocks list for any particular size is empty, the respective
80 FLT slot is zero. Sizes of free blocks in one list MUST NOT overlap with sizes
81 of free lists in other list. For example, even though a free block of size 2
82 technically is of minimal size >= 1, it MUST NOT be put to the list for slot 0
83 (minimal size 1), but in slot 1( minimal size 2).
84
85 slot 0: sizes [1, 2)
86 slot 1: sizes [2, 4)
87 slot 2: sizes [4, 8)
88 ...
89 slot 11: sizes [2048, 4096)
90 slot 12: sizes [4096, 4112)
91 slot 13: sizes [4112, inf)
92
93 The last FLT slot collects all free blocks bigger than its minimal size. That
94 still respects the 'no overlap' invariant.
95
96 File blocks
97
98 A block is a linear, contiguous sequence of atoms. The first and last atoms of
99 a block provide information about, for example, whether the block is free or
100 used, what is the size of the block, etc. Details are discussed elsewhere. The
101 first block of a file starts immediately after FLT, ie. at file offset
102 112(0x70).
103
104 Block atoms
105
106 An atom is a fixed size piece of a block (and thus of a file too); it is 16
107 bytes long. A consequence is that for a valid file:
108
109 filesize == 0 (mod 16)
110
111 The first atom of the first block is considered to be atom #1.
112
113 Block handles
114
115 A handle is an integer referring to a block. The reference is the number of the
116 atom the block starts with. Put in other way:
117
118 handle == offset/16 - 6
119 offset == 16 * (handle + 6)
120
121 `offset` is the offset of the first byte of the block, measured in bytes
122 - as in fseek(3). Handle has type `int64`, but only the lower 7 bytes may be
123 nonzero while referring to a block, both in code as well as when persisted in
124 the the file's internal bookkeeping structures - see 'Block types' bellow. So a
125 handle is effectively only `uint56`. This also means that the maximum usable
126 size of a file is 2^56 atoms. That is 2^60 bytes == 1 exabyte (10^18 bytes).
127
128 Nil handles
129
130 A handle with numeric value of '0' refers to no block.
131
132 Zero padding
133
134 A padding is used to round-up a block size to be a whole number of atoms. Any
135 padding, if present, MUST be all zero bytes. Note that the size of padding is
136 in [0, 15].
137
138 Content wiping
139
140 When a block is deallocated, its data content is not wiped as the added
141 overhead may be substantial while not necessarily needed. Client code should
142 however overwrite the content of any block having sensitive data with eg. zeros
143 (good compression) - before deallocating the block.
144
145 Block tags
146
147 Every block is tagged in its first byte (a head tag) and last byte (tail tag).
148 Block types are:
149
150 1. Short content used block (head tags 0x00-0xFB)
151 2. Long content used block (head tag 0xFC)
152 3. Relocated used block (head tag 0xFD)
153 4. Short, single atom, free block (head tag 0xFE)
154 5. Long free block (head tag 0xFF)
155
156 Note: Relocated used block, 3. above (head tag 0xFD) MUST NOT refer to blocks
157 other then 1. or 2. above (head tags 0x00-0xFC).
158
159 Content blocks
160
161 Used blocks (head tags 0x00-0xFC) tail tag distinguish used/unused block and if
162 content is compressed or not.
163
164 Content compression
165
166 The tail flag of an used block is one of
167
168 CC == 0 // Content is not compressed.
169 CC == 1 // Content is in zappy compression format.
170
171 If compression of written content is enabled, there are two cases: If
172 compressed size < original size then the compressed content should be written
173 if it will save at least one atom of the block. If compressed size >= original
174 size then the compressed content should not be used.
175
176 It's recommended to use compression. For example the BTrees implementation
177 assumes compression is used. Using compression may cause a slowdown in some
178 cases while it may as well cause a speedup.
179
180 Short content block
181
182 Short content block carries content of length between N == 0(0x00) and N ==
183 251(0xFB) bytes.
184
185 |<-first atom start ... last atom end->|
186 +---++-- ... --+-- ... --++------+
187 | 0 || 1... | 0x*...0x*E || 0x*F |
188 +---++-- ... --+-- ... --++------+
189 | N || content | padding || CC |
190 +---++-- ... --+-- ... --++------+
191
192 A == (N+1)/16 + 1 // The number of atoms in the block [1, 16]
193 padding == 15 - (N+1)%16 // Length of the zero padding
194
195 Long content block
196
197 Long content block carries content of length between N == 252(0xFC) and N ==
198 65787(0x100FB) bytes.
199
200 |<-first atom start ... last atom end->|
201 +------++------+-- ... --+-- ... --++------+
202 | 0 || 1..2 | 3... | 0x*...0x*E || 0x*F |
203 +------++------+-- ... --+-- ... --++------+
204 | 0xFC || M | content | padding || CC |
205 +------++------+-- ... --+-- ... --++------+
206
207 A == (N+3)/16 + 1 // The number of atoms in the block [16, 4112]
208 M == N % 0x10000 // Stored as 2 bytes in network byte order
209 padding == 15 - (N+3)%16 // Length of the zero padding
210
211 Relocated used block
212
213 Relocated block allows to permanently assign a handle to some content and
214 resize the content anytime afterwards without having to update all the possible
215 existing references; the handle can be constant while the content size may be
216 dynamic. When relocating a block, any space left by the original block content,
217 above this single atom block, MUST be reclaimed.
218
219 Relocations MUST point only to a used short or long block == blocks with tags
220 0x00...0xFC.
221
222 +------++------+---------++----+
223 | 0 || 1..7 | 8...14 || 15 |
224 +------++------+---------++----+
225 | 0xFD || H | padding || 0 |
226 +------++------+---------++----+
227
228 H is the handle of the relocated block in network byte order.
229
230 Free blocks
231
232 Free blocks are the result of space deallocation. Free blocks are organized in
233 one or more doubly linked lists, abstracted by the FLT interface. Free blocks
234 MUST be "registered" by putting them in such list. Allocator MUST reuse a big
235 enough free block, if such exists, before growing the file size. When a free
236 block is created by deallocation or reallocation it MUST be joined with any
237 adjacently existing free blocks before "registering". If the resulting free
238 block is now a last block of a file, the free block MUST be discarded and the
239 file size MUST be truncated accordingly instead. Put differently, there MUST
240 NOT ever be a free block at the file end.
241
242 A single free atom
243
244 Is an unused block of size 1 atom.
245
246 +------++------+--------++------+
247 | 0 || 1..7 | 8...14 || 15 |
248 +------++------+--------++------+
249 | 0xFE || P | N || 0xFE |
250 +------++------+--------++------+
251
252 P and N, stored in network byte order, are the previous and next free block
253 handles in the doubly linked list to which this free block belongs.
254
255 A long unused block
256
257 Is an unused block of size > 1 atom.
258
259 +------++------+-------+---------+- ... -+----------++------+
260 | 0 || 1..7 | 8..14 | 15...21 | | Z-7..Z-1 || Z |
261 +------++------+-------+---------+- ... -+----------++------+
262 | 0xFF || S | P | N | Leak | S || 0xFF |
263 +------++------+-------+---------+- ... -+----------++------+
264
265 Z == 16 * S - 1
266
267 S is the size of this unused block in atoms. P and N are the previous and next
268 free block handles in the doubly linked list to which this free block belongs.
269 Leak contains any data the block had before deallocating this block. See also
270 the subtitle 'Content wiping' above. S, P and N are stored in network byte
271 order. Large free blocks may trigger a consideration of file hole punching of
272 the Leak field - for some value of 'large'.
273
274 Note: Allocator methods vs CRUD[1]:
275
276 Alloc [C]reate
277 Get [R]ead
278 Realloc [U]pdate
279 Free [D]elete
280
281 Note: No Allocator method returns io.EOF.
282
283 [1]: http://en.wikipedia.org/wiki/Create,_read,_update_and_delete
284
285 */
286 type Allocator struct {
287 f Filer
288 flt flt
289 Compress bool // enables content compression
290 cache cache
291 m map[int64]*node
292 lru lst
293 expHit int64
294 expMiss int64
295 cacheSz int
296 hit uint16
297 miss uint16
298 mu sync.Mutex
299 }
300
301 // NewAllocator returns a new Allocator. To open an existing file, pass its
302 // Filer. To create a "new" file, pass a Filer which file is of zero size.
303 func NewAllocator(f Filer, opts *Options) (a *Allocator, err error) {
304 if opts == nil { // Enforce *Options is always passed
305 return nil, errors.New("NewAllocator: nil opts passed")
306 }
307
308 a = &Allocator{
309 f: f,
310 cacheSz: 10,
311 }
312
313 a.cinit()
314 switch x := f.(type) {
315 case *RollbackFiler:
316 x.afterRollback = func() error {
317 a.cinit()
318 return a.flt.load(a.f, 0)
319 }
320 case *ACIDFiler0:
321 x.RollbackFiler.afterRollback = func() error {
322 a.cinit()
323 return a.flt.load(a.f, 0)
324 }
325 }
326
327 sz, err := f.Size()
328 if err != nil {
329 return
330 }
331
332 a.flt.init()
333 if sz == 0 {
334 var b [fltSz]byte
335 if err = a.f.BeginUpdate(); err != nil {
336 return
337 }
338
339 if _, err = f.WriteAt(b[:], 0); err != nil {
340 a.f.Rollback()
341 return
342 }
343
344 return a, a.f.EndUpdate()
345 }
346
347 return a, a.flt.load(f, 0)
348 }
349
350 // CacheStats reports cache statistics.
351 //
352 //TODO return a struct perhaps.
353 func (a *Allocator) CacheStats() (buffersUsed, buffersTotal int, bytesUsed, bytesTotal, hits, misses int64) {
354 buffersUsed = len(a.m)
355 buffersTotal = buffersUsed + len(a.cache)
356 bytesUsed = a.lru.size()
357 bytesTotal = bytesUsed + a.cache.size()
358 hits = a.expHit
359 misses = a.expMiss
360 return
361 }
362
363 func (a *Allocator) cinit() {
364 for h, n := range a.m {
365 a.cache.put(a.lru.remove(n))
366 delete(a.m, h)
367 }
368 if a.m == nil {
369 a.m = map[int64]*node{}
370 }
371 }
372
373 func (a *Allocator) cadd(b []byte, h int64) {
374 if len(a.m) < a.cacheSz {
375 n := a.cache.get(len(b))
376 n.h = h
377 copy(n.b, b)
378 a.m[h] = a.lru.pushFront(n)
379 return
380 }
381
382 // cache full
383 delete(a.m, a.cache.put(a.lru.removeBack()).h)
384 n := a.cache.get(len(b))
385 n.h = h
386 copy(n.b, b)
387 a.m[h] = a.lru.pushFront(n)
388 return
389 }
390
391 func (a *Allocator) cfree(h int64) {
392 n, ok := a.m[h]
393 if !ok { // must have been evicted
394 return
395 }
396
397 a.cache.put(a.lru.remove(n))
398 delete(a.m, h)
399 }
400
401 // Alloc allocates storage space for b and returns the handle of the new block
402 // with content set to b or an error, if any. The returned handle is valid only
403 // while the block is used - until the block is deallocated. No two valid
404 // handles share the same value within the same Filer, but any value of a
405 // handle not referring to any used block may become valid any time as a result
406 // of Alloc.
407 //
408 // Invoking Alloc on an empty Allocator is guaranteed to return handle with
409 // value 1. The intended use of content of handle 1 is a root "directory" of
410 // other data held by an Allocator.
411 //
412 // Passing handles not obtained initially from Alloc or not anymore valid to
413 // any other Allocator methods can result in an irreparably corrupted database.
414 func (a *Allocator) Alloc(b []byte) (handle int64, err error) {
415 buf := bufs.GCache.Get(zappy.MaxEncodedLen(len(b)))
416 defer bufs.GCache.Put(buf)
417 buf, _, cc, err := a.makeUsedBlock(buf, b)
418 if err != nil {
419 return
420 }
421
422 if handle, err = a.alloc(buf, cc); err == nil {
423 a.cadd(b, handle)
424 }
425 return
426 }
427
428 func (a *Allocator) alloc(b []byte, cc byte) (h int64, err error) {
429 rqAtoms := n2atoms(len(b))
430 if h = a.flt.find(rqAtoms); h == 0 { // must grow
431 var sz int64
432 if sz, err = a.f.Size(); err != nil {
433 return
434 }
435
436 h = off2h(sz)
437 err = a.writeUsedBlock(h, cc, b)
438 return
439 }
440
441 // Handle is the first item of a free blocks list.
442 tag, s, prev, next, err := a.nfo(h)
443 if err != nil {
444 return
445 }
446
447 if tag != tagFreeShort && tag != tagFreeLong {
448 err = &ErrILSEQ{Type: ErrExpFreeTag, Off: h2off(h), Arg: int64(tag)}
449 return
450 }
451
452 if prev != 0 {
453 err = &ErrILSEQ{Type: ErrHead, Off: h2off(h), Arg: prev}
454 return
455 }
456
457 if s < int64(rqAtoms) {
458 err = &ErrILSEQ{Type: ErrSmall, Arg: int64(rqAtoms), Arg2: s, Off: h2off(h)}
459 return
460 }
461
462 if err = a.unlink(h, s, prev, next); err != nil {
463 return
464 }
465
466 if s > int64(rqAtoms) {
467 freeH := h + int64(rqAtoms)
468 freeAtoms := s - int64(rqAtoms)
469 if err = a.link(freeH, freeAtoms); err != nil {
470 return
471 }
472 }
473 return h, a.writeUsedBlock(h, cc, b)
474 }
475
476 // Free deallocates the block referred to by handle or returns an error, if
477 // any.
478 //
479 // After Free succeeds, handle is invalid and must not be used.
480 //
481 // Handle must have been obtained initially from Alloc and must be still valid,
482 // otherwise a database may get irreparably corrupted.
483 func (a *Allocator) Free(handle int64) (err error) {
484 if handle <= 0 || handle > maxHandle {
485 return &ErrINVAL{"Allocator.Free: handle out of limits", handle}
486 }
487
488 a.cfree(handle)
489 return a.free(handle, 0, true)
490 }
491
492 func (a *Allocator) free(h, from int64, acceptRelocs bool) (err error) {
493 tag, atoms, _, n, err := a.nfo(h)
494 if err != nil {
495 return
496 }
497
498 switch tag {
499 default:
500 // nop
501 case tagUsedLong:
502 // nop
503 case tagUsedRelocated:
504 if !acceptRelocs {
505 return &ErrILSEQ{Type: ErrUnexpReloc, Off: h2off(h), Arg: h2off(from)}
506 }
507
508 if err = a.free(n, h, false); err != nil {
509 return
510 }
511 case tagFreeShort, tagFreeLong:
512 return &ErrINVAL{"Allocator.Free: attempt to free a free block at off", h2off(h)}
513 }
514
515 return a.free2(h, atoms)
516 }
517
518 func (a *Allocator) free2(h, atoms int64) (err error) {
519 sz, err := a.f.Size()
520 if err != nil {
521 return
522 }
523
524 ltag, latoms, lp, ln, err := a.leftNfo(h)
525 if err != nil {
526 return
527 }
528
529 if ltag != tagFreeShort && ltag != tagFreeLong {
530 latoms = 0
531 }
532
533 var rtag byte
534 var ratoms, rp, rn int64
535
536 isTail := h2off(h)+atoms*16 == sz
537 if !isTail {
538 if rtag, ratoms, rp, rn, err = a.nfo(h + atoms); err != nil {
539 return
540 }
541 }
542
543 if rtag != tagFreeShort && rtag != tagFreeLong {
544 ratoms = 0
545 }
546
547 switch {
548 case latoms == 0 && ratoms == 0:
549 // -> isolated <-
550 if isTail { // cut tail
551 return a.f.Truncate(h2off(h))
552 }
553
554 return a.link(h, atoms)
555 case latoms == 0 && ratoms != 0:
556 // right join ->
557 if err = a.unlink(h+atoms, ratoms, rp, rn); err != nil {
558 return
559 }
560
561 return a.link(h, atoms+ratoms)
562 case latoms != 0 && ratoms == 0:
563 // <- left join
564 if err = a.unlink(h-latoms, latoms, lp, ln); err != nil {
565 return
566 }
567
568 if isTail {
569 return a.f.Truncate(h2off(h - latoms))
570 }
571
572 return a.link(h-latoms, latoms+atoms)
573 }
574
575 // case latoms != 0 && ratoms != 0:
576 // <- middle join ->
577 lh, rh := h-latoms, h+atoms
578 if err = a.unlink(lh, latoms, lp, ln); err != nil {
579 return
580 }
581
582 // Prev unlink may have invalidated rp or rn
583 if _, _, rp, rn, err = a.nfo(rh); err != nil {
584 return
585 }
586
587 if err = a.unlink(rh, ratoms, rp, rn); err != nil {
588 return
589 }
590
591 return a.link(h-latoms, latoms+atoms+ratoms)
592 }
593
594 // Add a free block h to the appropriate free list
595 func (a *Allocator) link(h, atoms int64) (err error) {
596 if err = a.makeFree(h, atoms, 0, a.flt.head(atoms)); err != nil {
597 return
598 }
599
600 return a.flt.setHead(h, atoms, a.f)
601 }
602
603 // Remove free block h from the free list
604 func (a *Allocator) unlink(h, atoms, p, n int64) (err error) {
605 switch {
606 case p == 0 && n == 0:
607 // single item list, must be head
608 return a.flt.setHead(0, atoms, a.f)
609 case p == 0 && n != 0:
610 // head of list (has next item[s])
611 if err = a.prev(n, 0); err != nil {
612 return
613 }
614
615 // new head
616 return a.flt.setHead(n, atoms, a.f)
617 case p != 0 && n == 0:
618 // last item in list
619 return a.next(p, 0)
620 }
621 // case p != 0 && n != 0:
622 // intermediate item in a list
623 if err = a.next(p, n); err != nil {
624 return
625 }
626
627 return a.prev(n, p)
628 }
629
630 //TODO remove ?
631 // Return len(slice) == n, reuse src if possible.
632 func need(n int, src []byte) []byte {
633 if cap(src) < n {
634 bufs.GCache.Put(src)
635 return bufs.GCache.Get(n)
636 }
637
638 return src[:n]
639 }
640
641 // Get returns the data content of a block referred to by handle or an error if
642 // any. The returned slice may be a sub-slice of buf if buf was large enough
643 // to hold the entire content. Otherwise, a newly allocated slice will be
644 // returned. It is valid to pass a nil buf.
645 //
646 // If the content was stored using compression then it is transparently
647 // returned decompressed.
648 //
649 // Handle must have been obtained initially from Alloc and must be still valid,
650 // otherwise invalid data may be returned without detecting the error.
651 //
652 // Get is safe for concurrent access by multiple goroutines iff no other
653 // goroutine mutates the DB.
654 func (a *Allocator) Get(buf []byte, handle int64) (b []byte, err error) {
655 buf = buf[:cap(buf)]
656 a.mu.Lock() // X1+
657 if n, ok := a.m[handle]; ok {
658 a.lru.moveToFront(n)
659 b = need(len(n.b), buf)
660 copy(b, n.b)
661 a.expHit++
662 a.hit++
663 a.mu.Unlock() // X1-
664 return
665 }
666
667 a.expMiss++
668 a.miss++
669 if a.miss > 10 && len(a.m) < 500 {
670 if 100*a.hit/a.miss < 95 {
671 a.cacheSz++
672 }
673 a.hit, a.miss = 0, 0
674 }
675 a.mu.Unlock() // X1-
676
677 defer func(h int64) {
678 if err == nil {
679 a.mu.Lock() // X2+
680 a.cadd(b, h)
681 a.mu.Unlock() // X2-
682 }
683 }(handle)
684
685 first := bufs.GCache.Get(16)
686 defer bufs.GCache.Put(first)
687 relocated := false
688 relocSrc := handle
689 reloc:
690 if handle <= 0 || handle > maxHandle {
691 return nil, &ErrINVAL{"Allocator.Get: handle out of limits", handle}
692 }
693
694 off := h2off(handle)
695 if err = a.read(first, off); err != nil {
696 return
697 }
698
699 switch tag := first[0]; tag {
700 default:
701 dlen := int(tag)
702 atoms := n2atoms(dlen)
703 switch atoms {
704 case 1:
705 switch tag := first[15]; tag {
706 default:
707 return nil, &ErrILSEQ{Type: ErrTailTag, Off: off, Arg: int64(tag)}
708 case tagNotCompressed:
709 b = need(dlen, buf)
710 copy(b, first[1:])
711 return
712 case tagCompressed:
713 return zappy.Decode(buf, first[1:dlen+1])
714 }
715 default:
716 cc := bufs.GCache.Get(1)
717 defer bufs.GCache.Put(cc)
718 dlen := int(tag)
719 atoms := n2atoms(dlen)
720 tailOff := off + 16*int64(atoms) - 1
721 if err = a.read(cc, tailOff); err != nil {
722 return
723 }
724
725 switch tag := cc[0]; tag {
726 default:
727 return nil, &ErrILSEQ{Type: ErrTailTag, Off: off, Arg: int64(tag)}
728 case tagNotCompressed:
729 b = need(dlen, buf)
730 off += 1
731 if err = a.read(b, off); err != nil {
732 b = buf[:0]
733 }
734 return
735 case tagCompressed:
736 zbuf := bufs.GCache.Get(dlen)
737 defer bufs.GCache.Put(zbuf)
738 off += 1
739 if err = a.read(zbuf, off); err != nil {
740 return buf[:0], err
741 }
742
743 return zappy.Decode(buf, zbuf)
744 }
745 }
746 case 0:
747 return buf[:0], nil
748 case tagUsedLong:
749 cc := bufs.GCache.Get(1)
750 defer bufs.GCache.Put(cc)
751 dlen := m2n(int(first[1])<<8 | int(first[2]))
752 atoms := n2atoms(dlen)
753 tailOff := off + 16*int64(atoms) - 1
754 if err = a.read(cc, tailOff); err != nil {
755 return
756 }
757
758 switch tag := cc[0]; tag {
759 default:
760 return nil, &ErrILSEQ{Type: ErrTailTag, Off: off, Arg: int64(tag)}
761 case tagNotCompressed:
762 b = need(dlen, buf)
763 off += 3
764 if err = a.read(b, off); err != nil {
765 b = buf[:0]
766 }
767 return
768 case tagCompressed:
769 zbuf := bufs.GCache.Get(dlen)
770 defer bufs.GCache.Put(zbuf)
771 off += 3
772 if err = a.read(zbuf, off); err != nil {
773 return buf[:0], err
774 }
775
776 return zappy.Decode(buf, zbuf)
777 }
778 case tagFreeShort, tagFreeLong:
779 return nil, &ErrILSEQ{Type: ErrExpUsedTag, Off: off, Arg: int64(tag)}
780 case tagUsedRelocated:
781 if relocated {
782 return nil, &ErrILSEQ{Type: ErrUnexpReloc, Off: off, Arg: relocSrc}
783 }
784
785 handle = b2h(first[1:])
786 relocated = true
787 goto reloc
788 }
789 }
790
791 var reallocTestHook bool
792
793 // Realloc sets the content of a block referred to by handle or returns an
794 // error, if any.
795 //
796 // Handle must have been obtained initially from Alloc and must be still valid,
797 // otherwise a database may get irreparably corrupted.
798 func (a *Allocator) Realloc(handle int64, b []byte) (err error) {
799 if handle <= 0 || handle > maxHandle {
800 return &ErrINVAL{"Realloc: handle out of limits", handle}
801 }
802
803 a.cfree(handle)
804 if err = a.realloc(handle, b); err != nil {
805 return
806 }
807
808 if reallocTestHook {
809 if err = cacheAudit(a.m, &a.lru); err != nil {
810 return
811 }
812 }
813
814 a.cadd(b, handle)
815 return
816 }
817
818 func (a *Allocator) realloc(handle int64, b []byte) (err error) {
819 var dlen, needAtoms0 int
820
821 b8 := bufs.GCache.Get(8)
822 defer bufs.GCache.Put(b8)
823 dst := bufs.GCache.Get(zappy.MaxEncodedLen(len(b)))
824 defer bufs.GCache.Put(dst)
825 b, needAtoms0, cc, err := a.makeUsedBlock(dst, b)
826 if err != nil {
827 return
828 }
829
830 needAtoms := int64(needAtoms0)
831 off := h2off(handle)
832 if err = a.read(b8[:], off); err != nil {
833 return
834 }
835
836 switch tag := b8[0]; tag {
837 default:
838 dlen = int(b8[0])
839 case tagUsedLong:
840 dlen = m2n(int(b8[1])<<8 | int(b8[2]))
841 case tagUsedRelocated:
842 if err = a.free(b2h(b8[1:]), handle, false); err != nil {
843 return err
844 }
845
846 dlen = 0
847 case tagFreeShort, tagFreeLong:
848 return &ErrINVAL{"Allocator.Realloc: invalid handle", handle}
849 }
850
851 atoms := int64(n2atoms(dlen))
852 retry:
853 switch {
854 case needAtoms < atoms:
855 // in place shrink
856 if err = a.writeUsedBlock(handle, cc, b); err != nil {
857 return
858 }
859
860 fh, fa := handle+needAtoms, atoms-needAtoms
861 sz, err := a.f.Size()
862 if err != nil {
863 return err
864 }
865
866 if h2off(fh)+16*fa == sz {
867 return a.f.Truncate(h2off(fh))
868 }
869
870 return a.free2(fh, fa)
871 case needAtoms == atoms:
872 // in place replace
873 return a.writeUsedBlock(handle, cc, b)
874 }
875
876 // case needAtoms > atoms:
877 // in place extend or relocate
878 var sz int64
879 if sz, err = a.f.Size(); err != nil {
880 return
881 }
882
883 off = h2off(handle)
884 switch {
885 case off+atoms*16 == sz:
886 // relocating tail block - shortcut
887 return a.writeUsedBlock(handle, cc, b)
888 default:
889 if off+atoms*16 < sz {
890 // handle is not a tail block, check right neighbour
891 rh := handle + atoms
892 rtag, ratoms, p, n, e := a.nfo(rh)
893 if e != nil {
894 return e
895 }
896
897 if rtag == tagFreeShort || rtag == tagFreeLong {
898 // Right neighbour is a free block
899 if needAtoms <= atoms+ratoms {
900 // can expand in place
901 if err = a.unlink(rh, ratoms, p, n); err != nil {
902 return
903 }
904
905 atoms += ratoms
906 goto retry
907
908 }
909 }
910 }
911 }
912
913 if atoms > 1 {
914 if err = a.realloc(handle, nil); err != nil {
915 return
916 }
917 }
918
919 var newH int64
920 if newH, err = a.alloc(b, cc); err != nil {
921 return err
922 }
923
924 rb := bufs.GCache.Cget(16)
925 defer bufs.GCache.Put(rb)
926 rb[0] = tagUsedRelocated
927 h2b(rb[1:], newH)
928 if err = a.writeAt(rb[:], h2off(handle)); err != nil {
929 return
930 }
931
932 return a.writeUsedBlock(newH, cc, b)
933 }
934
935 func (a *Allocator) writeAt(b []byte, off int64) (err error) {
936 var n int
937 if n, err = a.f.WriteAt(b, off); err != nil {
938 return
939 }
940
941 if n != len(b) {
942 err = io.ErrShortWrite
943 }
944 return
945 }
946
947 func (a *Allocator) write(off int64, b ...[]byte) (err error) {
948 rq := 0
949 for _, part := range b {
950 rq += len(part)
951 }
952 buf := bufs.GCache.Get(rq)
953 defer bufs.GCache.Put(buf)
954 buf = buf[:0]
955 for _, part := range b {
956 buf = append(buf, part...)
957 }
958 return a.writeAt(buf, off)
959 }
960
961 func (a *Allocator) read(b []byte, off int64) (err error) {
962 var rn int
963 if rn, err = a.f.ReadAt(b, off); rn != len(b) {
964 return &ErrILSEQ{Type: ErrOther, Off: off, More: err}
965 }
966
967 return nil
968 }
969
970 // nfo returns h's tag. If it's a free block then return also (s)ize (in
971 // atoms), (p)rev and (n)ext. If it's a used block then only (s)ize is returned
972 // (again in atoms). If it's a used relocate block then (n)ext is set to the
973 // relocation target handle.
974 func (a *Allocator) nfo(h int64) (tag byte, s, p, n int64, err error) {
975 off := h2off(h)
976 rq := int64(22)
977 sz, err := a.f.Size()
978 if err != nil {
979 return
980 }
981
982 if off+rq >= sz {
983 if rq = sz - off; rq < 15 {
984 err = io.ErrUnexpectedEOF
985 return
986 }
987 }
988
989 buf := bufs.GCache.Get(22)
990 defer bufs.GCache.Put(buf)
991 if err = a.read(buf[:rq], off); err != nil {
992 return
993 }
994
995 switch tag = buf[0]; tag {
996 default:
997 s = int64(n2atoms(int(tag)))
998 case tagUsedLong:
999 s = int64(n2atoms(m2n(int(buf[1])<<8 | int(buf[2]))))
1000 case tagFreeLong:
1001 if rq < 22 {
1002 err = io.ErrUnexpectedEOF
1003 return
1004 }
1005
1006 s, p, n = b2h(buf[1:]), b2h(buf[8:]), b2h(buf[15:])
1007 case tagUsedRelocated:
1008 s, n = 1, b2h(buf[1:])
1009 case tagFreeShort:
1010 s, p, n = 1, b2h(buf[1:]), b2h(buf[8:])
1011 }
1012 return
1013 }
1014
1015 // leftNfo returns nfo for h's left neighbor if h > 1 and the left neighbor is
1016 // a free block. Otherwise all zero values are returned instead.
1017 func (a *Allocator) leftNfo(h int64) (tag byte, s, p, n int64, err error) {
1018 if !(h > 1) {
1019 return
1020 }
1021
1022 buf := bufs.GCache.Get(8)
1023 defer bufs.GCache.Put(buf)
1024 off := h2off(h)
1025 if err = a.read(buf[:], off-8); err != nil {
1026 return
1027 }
1028
1029 switch tag := buf[7]; tag {
1030 case tagFreeShort:
1031 return a.nfo(h - 1)
1032 case tagFreeLong:
1033 return a.nfo(h - b2h(buf[:]))
1034 }
1035 return
1036 }
1037
1038 // Set h.prev = p
1039 func (a *Allocator) prev(h, p int64) (err error) {
1040 b := bufs.GCache.Get(7)
1041 defer bufs.GCache.Put(b)
1042 off := h2off(h)
1043 if err = a.read(b[:1], off); err != nil {
1044 return
1045 }
1046
1047 switch tag := b[0]; tag {
1048 default:
1049 return &ErrILSEQ{Type: ErrExpFreeTag, Off: off, Arg: int64(tag)}
1050 case tagFreeShort:
1051 off += 1
1052 case tagFreeLong:
1053 off += 8
1054 }
1055 return a.writeAt(h2b(b[:7], p), off)
1056 }
1057
1058 // Set h.next = n
1059 func (a *Allocator) next(h, n int64) (err error) {
1060 b := bufs.GCache.Get(7)
1061 defer bufs.GCache.Put(b)
1062 off := h2off(h)
1063 if err = a.read(b[:1], off); err != nil {
1064 return
1065 }
1066
1067 switch tag := b[0]; tag {
1068 default:
1069 return &ErrILSEQ{Type: ErrExpFreeTag, Off: off, Arg: int64(tag)}
1070 case tagFreeShort:
1071 off += 8
1072 case tagFreeLong:
1073 off += 15
1074 }
1075 return a.writeAt(h2b(b[:7], n), off)
1076 }
1077
1078 // Make the filer image @h a free block.
1079 func (a *Allocator) makeFree(h, atoms, prev, next int64) (err error) {
1080 buf := bufs.GCache.Get(22)
1081 defer bufs.GCache.Put(buf)
1082 switch {
1083 case atoms == 1:
1084 buf[0], buf[15] = tagFreeShort, tagFreeShort
1085 h2b(buf[1:], prev)
1086 h2b(buf[8:], next)
1087 if err = a.write(h2off(h), buf[:16]); err != nil {
1088 return
1089 }
1090 default:
1091
1092 buf[0] = tagFreeLong
1093 h2b(buf[1:], atoms)
1094 h2b(buf[8:], prev)
1095 h2b(buf[15:], next)
1096 if err = a.write(h2off(h), buf[:22]); err != nil {
1097 return
1098 }
1099
1100 h2b(buf[:], atoms)
1101 buf[7] = tagFreeLong
1102 if err = a.write(h2off(h+atoms)-8, buf[:8]); err != nil {
1103 return
1104 }
1105 }
1106 if prev != 0 {
1107 if err = a.next(prev, h); err != nil {
1108 return
1109 }
1110 }
1111
1112 if next != 0 {
1113 err = a.prev(next, h)
1114 }
1115 return
1116 }
1117
1118 func (a *Allocator) makeUsedBlock(dst []byte, b []byte) (w []byte, rqAtoms int, cc byte, err error) {
1119 cc = tagNotCompressed
1120 w = b
1121
1122 var n int
1123 if n = len(b); n > maxRq {
1124 return nil, 0, 0, &ErrINVAL{"Allocator.makeUsedBlock: content size out of limits", n}
1125 }
1126
1127 rqAtoms = n2atoms(n)
1128 if a.Compress && n > 14 { // attempt compression
1129 if dst, err = zappy.Encode(dst, b); err != nil {
1130 return
1131 }
1132
1133 n2 := len(dst)
1134 if rqAtoms2 := n2atoms(n2); rqAtoms2 < rqAtoms { // compression saved at least a single atom
1135 w, n, rqAtoms, cc = dst, n2, rqAtoms2, tagCompressed
1136 }
1137 }
1138 return
1139 }
1140
1141 func (a *Allocator) writeUsedBlock(h int64, cc byte, b []byte) (err error) {
1142 n := len(b)
1143 rq := n2atoms(n) << 4
1144 buf := bufs.GCache.Get(rq)
1145 defer bufs.GCache.Put(buf)
1146 switch n <= maxShort {
1147 case true:
1148 buf[0] = byte(n)
1149 copy(buf[1:], b)
1150 case false:
1151 m := n2m(n)
1152 buf[0], buf[1], buf[2] = tagUsedLong, byte(m>>8), byte(m)
1153 copy(buf[3:], b)
1154 }
1155 if p := n2padding(n); p != 0 {
1156 copy(buf[rq-1-p:], zeros[:])
1157 }
1158 buf[rq-1] = cc
1159 return a.writeAt(buf, h2off(h))
1160 }
1161
1162 func (a *Allocator) verifyUnused(h, totalAtoms int64, tag byte, log func(error) bool, fast bool) (atoms, prev, next int64, err error) {
1163 switch tag {
1164 default:
1165 panic("internal error")
1166 case tagFreeShort:
1167 var b [16]byte
1168 off := h2off(h)
1169 if err = a.read(b[:], off); err != nil {
1170 return
1171 }
1172
1173 if b[15] != tagFreeShort {
1174 err = &ErrILSEQ{Type: ErrShortFreeTailTag, Off: off, Arg: int64(b[15])}
1175 log(err)
1176 return
1177 }
1178
1179 atoms, prev, next = 1, b2h(b[1:]), b2h(b[8:])
1180 case tagFreeLong:
1181 var b [22]byte
1182 off := h2off(h)
1183 if err = a.read(b[:], off); err != nil {
1184 return
1185 }
1186
1187 atoms, prev, next = b2h(b[1:]), b2h(b[8:]), b2h(b[15:])
1188 if fast {
1189 return
1190 }
1191
1192 if atoms < 2 {
1193 err = &ErrILSEQ{Type: ErrLongFreeBlkTooShort, Off: off, Arg: int64(atoms)}
1194 break
1195 }
1196
1197 if h+atoms-1 > totalAtoms {
1198 err = &ErrILSEQ{Type: ErrLongFreeBlkTooLong, Off: off, Arg: atoms}
1199 break
1200 }
1201
1202 if prev > totalAtoms {
1203 err = &ErrILSEQ{Type: ErrLongFreePrevBeyondEOF, Off: off, Arg: next}
1204 break
1205 }
1206
1207 if next > totalAtoms {
1208 err = &ErrILSEQ{Type: ErrLongFreeNextBeyondEOF, Off: off, Arg: next}
1209 break
1210 }
1211
1212 toff := h2off(h+atoms) - 8
1213 if err = a.read(b[:8], toff); err != nil {
1214 return
1215 }
1216
1217 if b[7] != tag {
1218 err = &ErrILSEQ{Type: ErrLongFreeTailTag, Off: off, Arg: int64(b[7])}
1219 break
1220 }
1221
1222 if s2 := b2h(b[:]); s2 != atoms {
1223 err = &ErrILSEQ{Type: ErrVerifyTailSize, Off: off, Arg: atoms, Arg2: s2}
1224 break
1225 }
1226
1227 }
1228 if err != nil {
1229 log(err)
1230 }
1231 return
1232 }
1233
1234 func (a *Allocator) verifyUsed(h, totalAtoms int64, tag byte, buf, ubuf []byte, log func(error) bool, fast bool) (compressed bool, dlen int, atoms, link int64, err error) {
1235 var (
1236 padding int
1237 doff int64
1238 padZeros [15]byte
1239 tailBuf [16]byte
1240 )
1241
1242 switch tag {
1243 default: // Short used
1244 dlen = int(tag)
1245 atoms = int64((dlen+1)/16) + 1
1246 padding = 15 - (dlen+1)%16
1247 doff = h2off(h) + 1
1248 case tagUsedLong:
1249 off := h2off(h) + 1
1250 var b2 [2]byte
1251 if err = a.read(b2[:], off); err != nil {
1252 return
1253 }
1254
1255 dlen = m2n(int(b2[0])<<8 | int(b2[1]))
1256 atoms = int64((dlen+3)/16) + 1
1257 padding = 15 - (dlen+3)%16
1258 doff = h2off(h) + 3
1259 case tagUsedRelocated:
1260 dlen = 7
1261 atoms = 1
1262 padding = 7
1263 doff = h2off(h) + 1
1264 case tagFreeShort, tagFreeLong:
1265 panic("internal error")
1266 }
1267
1268 if fast {
1269 if tag == tagUsedRelocated {
1270 dlen = 0
1271 if err = a.read(buf[:7], doff); err != nil {
1272 return
1273 }
1274
1275 link = b2h(buf)
1276 }
1277
1278 return false, dlen, atoms, link, nil
1279 }
1280
1281 if ok := h+atoms-1 <= totalAtoms; !ok { // invalid last block
1282 err = &ErrILSEQ{Type: ErrVerifyUsedSpan, Off: h2off(h), Arg: atoms}
1283 log(err)
1284 return
1285 }
1286
1287 tailsz := 1 + padding
1288 off := h2off(h) + 16*atoms - int64(tailsz)
1289 if err = a.read(tailBuf[:tailsz], off); err != nil {
1290 return false, 0, 0, 0, err
1291 }
1292
1293 if ok := bytes.Equal(padZeros[:padding], tailBuf[:padding]); !ok {
1294 err = &ErrILSEQ{Type: ErrVerifyPadding, Off: h2off(h)}
1295 log(err)
1296 return
1297 }
1298
1299 var cc byte
1300 switch cc = tailBuf[padding]; cc {
1301 default:
1302 err = &ErrILSEQ{Type: ErrTailTag, Off: h2off(h)}
1303 log(err)
1304 return
1305 case tagCompressed:
1306 compressed = true
1307 if tag == tagUsedRelocated {
1308 err = &ErrILSEQ{Type: ErrTailTag, Off: h2off(h)}
1309 log(err)
1310 return
1311 }
1312
1313 fallthrough
1314 case tagNotCompressed:
1315 if err = a.read(buf[:dlen], doff); err != nil {
1316 return false, 0, 0, 0, err
1317 }
1318 }
1319
1320 if cc == tagCompressed {
1321 if ubuf, err = zappy.Decode(ubuf, buf[:dlen]); err != nil || len(ubuf) > maxRq {
1322 err = &ErrILSEQ{Type: ErrDecompress, Off: h2off(h)}
1323 log(err)
1324 return
1325 }
1326
1327 dlen = len(ubuf)
1328 }
1329
1330 if tag == tagUsedRelocated {
1331 link = b2h(buf)
1332 if link == 0 {
1333 err = &ErrILSEQ{Type: ErrNullReloc, Off: h2off(h)}
1334 log(err)
1335 return
1336 }
1337
1338 if link > totalAtoms { // invalid last block
1339 err = &ErrILSEQ{Type: ErrRelocBeyondEOF, Off: h2off(h), Arg: link}
1340 log(err)
1341 return
1342 }
1343 }
1344
1345 return
1346 }
1347
1348 var nolog = func(error) bool { return false }
1349
1350 // Verify attempts to find any structural errors in a Filer wrt the
1351 // organization of it as defined by Allocator. 'bitmap' is a scratch pad for
1352 // necessary bookkeeping and will grow to at most to Allocator's
1353 // Filer.Size()/128 (0,78%). Any problems found are reported to 'log' except
1354 // non verify related errors like disk read fails etc. If 'log' returns false
1355 // or the error doesn't allow to (reliably) continue, the verification process
1356 // is stopped and an error is returned from the Verify function. Passing a nil
1357 // log works like providing a log function always returning false. Any
1358 // non-structural errors, like for instance Filer read errors, are NOT reported
1359 // to 'log', but returned as the Verify's return value, because Verify cannot
1360 // proceed in such cases. Verify returns nil only if it fully completed
1361 // verifying Allocator's Filer without detecting any error.
1362 //
1363 // It is recommended to limit the number reported problems by returning false
1364 // from 'log' after reaching some limit. Huge and corrupted DB can produce an
1365 // overwhelming error report dataset.
1366 //
1367 // The verifying process will scan the whole DB at least 3 times (a trade
1368 // between processing space and time consumed). It doesn't read the content of
1369 // free blocks above the head/tail info bytes. If the 3rd phase detects lost
1370 // free space, then a 4th scan (a faster one) is performed to precisely report
1371 // all of them.
1372 //
1373 // If the DB/Filer to be verified is reasonably small, respective if its
1374 // size/128 can comfortably fit within process's free memory, then it is
1375 // recommended to consider using a MemFiler for the bit map.
1376 //
1377 // Statistics are returned via 'stats' if non nil. The statistics are valid
1378 // only if Verify succeeded, ie. it didn't reported anything to log and it
1379 // returned a nil error.
1380 func (a *Allocator) Verify(bitmap Filer, log func(error) bool, stats *AllocStats) (err error) {
1381 if log == nil {
1382 log = nolog
1383 }
1384
1385 n, err := bitmap.Size()
1386 if err != nil {
1387 return
1388 }
1389
1390 if n != 0 {
1391 return &ErrINVAL{"Allocator.Verify: bit map initial size non zero (%d)", n}
1392 }
1393
1394 var bits int64
1395 bitMask := [8]byte{1, 2, 4, 8, 16, 32, 64, 128}
1396 byteBuf := []byte{0}
1397
1398 //DONE
1399 // +performance, this implementation is hopefully correct but _very_
1400 // naive, probably good as a prototype only. Use maybe a MemFiler
1401 // "cache" etc.
1402 // ----
1403 // Turns out the OS caching is as effective as it can probably get.
1404 bit := func(on bool, h int64) (wasOn bool, err error) {
1405 m := bitMask[h&7]
1406 off := h >> 3
1407 var v byte
1408 sz, err := bitmap.Size()
1409 if err != nil {
1410 return
1411 }
1412
1413 if off < sz {
1414 if n, err := bitmap.ReadAt(byteBuf, off); n != 1 {
1415 return false, &ErrILSEQ{Type: ErrOther, Off: off, More: fmt.Errorf("Allocator.Verify - reading bitmap: %s", err)}
1416 }
1417
1418 v = byteBuf[0]
1419 }
1420 switch wasOn = v&m != 0; on {
1421 case true:
1422 if !wasOn {
1423 v |= m
1424 bits++
1425 }
1426 case false:
1427 if wasOn {
1428 v ^= m
1429 bits--
1430 }
1431 }
1432 byteBuf[0] = v
1433 if n, err := bitmap.WriteAt(byteBuf, off); n != 1 || err != nil {
1434 return false, &ErrILSEQ{Type: ErrOther, Off: off, More: fmt.Errorf("Allocator.Verify - writing bitmap: %s", err)}
1435 }
1436
1437 return
1438 }
1439
1440 // Phase 1 - sequentially scan a.f to reliably determine block
1441 // boundaries. Set a bit for every block start.
1442 var (
1443 buf, ubuf [maxRq]byte
1444 prevH, h, atoms int64
1445 wasOn bool
1446 tag byte
1447 st = AllocStats{
1448 AllocMap: map[int64]int64{},
1449 FreeMap: map[int64]int64{},
1450 }
1451 dlen int
1452 )
1453
1454 fsz, err := a.f.Size()
1455 if err != nil {
1456 return
1457 }
1458
1459 ok := fsz%16 == 0
1460 totalAtoms := (fsz - fltSz) / atomLen
1461 if !ok {
1462 err = &ErrILSEQ{Type: ErrFileSize, Name: a.f.Name(), Arg: fsz}
1463 log(err)
1464 return
1465 }
1466
1467 st.TotalAtoms = totalAtoms
1468 prevTag := -1
1469 lastH := int64(-1)
1470
1471 for h = 1; h <= totalAtoms; h += atoms {
1472 prevH = h // For checking last block == used
1473
1474 off := h2off(h)
1475 if err = a.read(buf[:1], off); err != nil {
1476 return
1477 }
1478
1479 switch tag = buf[0]; tag {
1480 default: // Short used
1481 fallthrough
1482 case tagUsedLong, tagUsedRelocated:
1483 var compressed bool
1484 if compressed, dlen, atoms, _, err = a.verifyUsed(h, totalAtoms, tag, buf[:], ubuf[:], log, false); err != nil {
1485 return
1486 }
1487
1488 if compressed {
1489 st.Compression++
1490 }
1491 st.AllocAtoms += atoms
1492 switch {
1493 case tag == tagUsedRelocated:
1494 st.AllocMap[1]++
1495 st.Relocations++
1496 default:
1497 st.AllocMap[atoms]++
1498 st.AllocBytes += int64(dlen)
1499 st.Handles++
1500 }
1501 case tagFreeShort, tagFreeLong:
1502 if prevTag == tagFreeShort || prevTag == tagFreeLong {
1503 err = &ErrILSEQ{Type: ErrAdjacentFree, Off: h2off(lastH), Arg: off}
1504 log(err)
1505 return
1506 }
1507
1508 if atoms, _, _, err = a.verifyUnused(h, totalAtoms, tag, log, false); err != nil {
1509 return
1510 }
1511
1512 st.FreeMap[atoms]++
1513 st.FreeAtoms += atoms
1514 }
1515
1516 if wasOn, err = bit(true, h); err != nil {
1517 return
1518 }
1519
1520 if wasOn {
1521 panic("internal error")
1522 }
1523
1524 prevTag = int(tag)
1525 lastH = h
1526 }
1527
1528 if totalAtoms != 0 && (tag == tagFreeShort || tag == tagFreeLong) {
1529 err = &ErrILSEQ{Type: ErrFreeTailBlock, Off: h2off(prevH)}
1530 log(err)
1531 return
1532 }
1533
1534 // Phase 2 - check used blocks, turn off the map bit for every used
1535 // block.
1536 for h = 1; h <= totalAtoms; h += atoms {
1537 off := h2off(h)
1538 if err = a.read(buf[:1], off); err != nil {
1539 return
1540 }
1541
1542 var link int64
1543 switch tag = buf[0]; tag {
1544 default: // Short used
1545 fallthrough
1546 case tagUsedLong, tagUsedRelocated:
1547 if _, _, atoms, link, err = a.verifyUsed(h, totalAtoms, tag, buf[:], ubuf[:], log, true); err != nil {
1548 return
1549 }
1550 case tagFreeShort, tagFreeLong:
1551 if atoms, _, _, err = a.verifyUnused(h, totalAtoms, tag, log, true); err != nil {
1552 return
1553 }
1554 }
1555
1556 turnoff := true
1557 switch tag {
1558 case tagUsedRelocated:
1559 if err = a.read(buf[:1], h2off(link)); err != nil {
1560 return
1561 }
1562
1563 switch linkedTag := buf[0]; linkedTag {
1564 case tagFreeShort, tagFreeLong, tagUsedRelocated:
1565 err = &ErrILSEQ{Type: ErrInvalidRelocTarget, Off: off, Arg: link}
1566 log(err)
1567 return
1568 }
1569
1570 case tagFreeShort, tagFreeLong:
1571 turnoff = false
1572 }
1573
1574 if !turnoff {
1575 continue
1576 }
1577
1578 if wasOn, err = bit(false, h); err != nil {
1579 return
1580 }
1581
1582 if !wasOn {
1583 panic("internal error")
1584 }
1585
1586 }
1587
1588 // Phase 3 - using the flt check heads link to proper free blocks. For
1589 // every free block, walk the list, verify the {next, prev} links and
1590 // turn the respective map bit off. After processing all free lists,
1591 // the map bits count should be zero. Otherwise there are "lost" free
1592 // blocks.
1593
1594 var prev, next, fprev, fnext int64
1595 rep := a.flt
1596
1597 for _, list := range rep {
1598 prev, next = 0, list.head
1599 for ; next != 0; prev, next = next, fnext {
1600 if wasOn, err = bit(false, next); err != nil {
1601 return
1602 }
1603
1604 if !wasOn {
1605 err = &ErrILSEQ{Type: ErrFLT, Off: h2off(next), Arg: h}
1606 log(err)
1607 return
1608 }
1609
1610 off := h2off(next)
1611 if err = a.read(buf[:1], off); err != nil {
1612 return
1613 }
1614
1615 switch tag = buf[0]; tag {
1616 default:
1617 panic("internal error")
1618 case tagFreeShort, tagFreeLong:
1619 if atoms, fprev, fnext, err = a.verifyUnused(next, totalAtoms, tag, log, true); err != nil {
1620 return
1621 }
1622
1623 if min := list.minSize; atoms < min {
1624 err = &ErrILSEQ{Type: ErrFLTSize, Off: h2off(next), Arg: atoms, Arg2: min}
1625 log(err)
1626 return
1627 }
1628
1629 if fprev != prev {
1630 err = &ErrILSEQ{Type: ErrFreeChaining, Off: h2off(next)}
1631 log(err)
1632 return
1633 }
1634 }
1635 }
1636
1637 }
1638
1639 if bits == 0 { // Verify succeeded
1640 if stats != nil {
1641 *stats = st
1642 }
1643 return
1644 }
1645
1646 // Phase 4 - if after phase 3 there are lost free blocks, report all of
1647 // them to 'log'
1648 for i := range ubuf { // setup zeros for compares
1649 ubuf[i] = 0
1650 }
1651
1652 var off, lh int64
1653 rem, err := bitmap.Size()
1654 if err != nil {
1655 return err
1656 }
1657
1658 for rem != 0 {
1659 rq := int(mathutil.MinInt64(64*1024, rem))
1660 var n int
1661 if n, err = bitmap.ReadAt(buf[:rq], off); n != rq {
1662 return &ErrILSEQ{Type: ErrOther, Off: off, More: fmt.Errorf("bitmap ReadAt(size %d, off %#x): %s", rq, off, err)}
1663 }
1664
1665 if !bytes.Equal(buf[:rq], ubuf[:rq]) {
1666 for d, v := range buf[:rq] {
1667 if v != 0 {
1668 for i, m := range bitMask {
1669 if v&m != 0 {
1670 lh = 8*(off+int64(d)) + int64(i)
1671 err = &ErrILSEQ{Type: ErrLostFreeBlock, Off: h2off(lh)}
1672 log(err)
1673 return
1674 }
1675 }
1676 }
1677 }
1678 }
1679
1680 off += int64(rq)
1681 rem -= int64(rq)
1682 }
1683
1684 return
1685 }
1686
1687 type fltSlot struct {
1688 head int64
1689 minSize int64
1690 }
1691
1692 func (f fltSlot) String() string {
1693 return fmt.Sprintf("head %#x, minSize %#x\n", f.head, f.minSize)
1694 }
1695
1696 type flt [14]fltSlot
1697
1698 func (f *flt) init() {
1699 sz := 1
1700 for i := range *f {
1701 f[i].minSize, f[i].head = int64(sz), 0
1702 sz <<= 1
1703 }
1704 f[13].minSize = 4112
1705 }
1706
1707 func (f *flt) load(fi Filer, off int64) (err error) {
1708 b := bufs.GCache.Get(fltSz)
1709 defer bufs.GCache.Put(b)
1710 if _, err = fi.ReadAt(b[:], off); err != nil {
1711 return
1712 }
1713
1714 for i := range *f {
1715 off := 8*i + 1
1716 f[i].head = b2h(b[off:])
1717 }
1718 return
1719 }
1720
1721 func (f *flt) find(rq int) (h int64) {
1722 switch {
1723 case rq < 1:
1724 panic(rq)
1725 case rq >= maxFLTRq:
1726 h, f[13].head = f[13].head, 0
1727 return
1728 default:
1729 g := f[mathutil.Log2Uint16(uint16(rq)):]
1730 for i := range g {
1731 p := &g[i]
1732 if rq <= int(p.minSize) {
1733 if h = p.head; h != 0 {
1734 p.head = 0
1735 return
1736 }
1737 }
1738 }
1739 return
1740 }
1741 }
1742
1743 func (f *flt) head(atoms int64) (h int64) {
1744 switch {
1745 case atoms < 1:
1746 panic(atoms)
1747 case atoms >= maxFLTRq:
1748 return f[13].head
1749 default:
1750 lg := mathutil.Log2Uint16(uint16(atoms))
1751 g := f[lg:]
1752 for i := range g {
1753 if atoms < g[i+1].minSize {
1754 return g[i].head
1755 }
1756 }
1757 panic("internal error")
1758 }
1759 }
1760
1761 func (f *flt) setHead(h, atoms int64, fi Filer) (err error) {
1762 switch {
1763 case atoms < 1:
1764 panic(atoms)
1765 case atoms >= maxFLTRq:
1766 b := bufs.GCache.Get(7)
1767 defer bufs.GCache.Put(b)
1768 if _, err = fi.WriteAt(h2b(b[:], h), 8*13+1); err != nil {
1769 return
1770 }
1771
1772 f[13].head = h
1773 return
1774 default:
1775 lg := mathutil.Log2Uint16(uint16(atoms))
1776 g := f[lg:]
1777 for i := range f {
1778 if atoms < g[i+1].minSize {
1779 b := bufs.GCache.Get(7)
1780 defer bufs.GCache.Put(b)
1781 if _, err = fi.WriteAt(h2b(b[:], h), 8*int64(i+lg)+1); err != nil {
1782 return
1783 }
1784
1785 g[i].head = h
1786 return
1787 }
1788 }
1789 panic("internal error")
1790 }
1791 }
1792
1793 func (f *flt) String() string {
1794 a := []string{}
1795 for i, v := range *f {
1796 a = append(a, fmt.Sprintf("[%2d] %s", i, v))
1797 }
1798 return strings.Join(a, "")
1799 }
1800
1801 type node struct {
1802 b []byte
1803 h int64
1804 prev, next *node
1805 }
1806
1807 type cache []*node
1808
1809 func (c *cache) get(n int) *node {
1810 r, _ := c.get2(n)
1811 return r
1812 }
1813
1814 func (c *cache) get2(n int) (r *node, isZeroed bool) {
1815 s := *c
1816 lens := len(s)
1817 if lens == 0 {
1818 return &node{b: make([]byte, n, mathutil.Min(2*n, maxBuf))}, true
1819 }
1820
1821 i := sort.Search(lens, func(x int) bool { return len(s[x].b) >= n })
1822 if i == lens {
1823 i--
1824 s[i].b, isZeroed = make([]byte, n, mathutil.Min(2*n, maxBuf)), true
1825 }
1826
1827 r = s[i]
1828 r.b = r.b[:n]
1829 copy(s[i:], s[i+1:])
1830 s = s[:lens-1]
1831 *c = s
1832 return
1833 }
1834
1835 func (c *cache) cget(n int) (r *node) {
1836 r, ok := c.get2(n)
1837 if ok {
1838 return
1839 }
1840
1841 for i := range r.b {
1842 r.b[i] = 0
1843 }
1844 return
1845 }
1846
1847 func (c *cache) size() (sz int64) {
1848 for _, n := range *c {
1849 sz += int64(cap(n.b))
1850 }
1851 return
1852 }
1853
1854 func (c *cache) put(n *node) *node {
1855 s := *c
1856 n.b = n.b[:cap(n.b)]
1857 lenb := len(n.b)
1858 lens := len(s)
1859 i := sort.Search(lens, func(x int) bool { return len(s[x].b) >= lenb })
1860 s = append(s, nil)
1861 copy(s[i+1:], s[i:])
1862 s[i] = n
1863 *c = s
1864 return n
1865 }
1866
1867 type lst struct {
1868 front, back *node
1869 }
1870
1871 func (l *lst) pushFront(n *node) *node {
1872 if l.front == nil {
1873 l.front, l.back, n.prev, n.next = n, n, nil, nil
1874 return n
1875 }
1876
1877 n.prev, n.next, l.front.prev, l.front = nil, l.front, n, n
1878 return n
1879 }
1880
1881 func (l *lst) remove(n *node) *node {
1882 if n.prev == nil {
1883 l.front = n.next
1884 } else {
1885 n.prev.next = n.next
1886 }
1887 if n.next == nil {
1888 l.back = n.prev
1889 } else {
1890 n.next.prev = n.prev
1891 }
1892 n.prev, n.next = nil, nil
1893 return n
1894 }
1895
1896 func (l *lst) removeBack() *node {
1897 return l.remove(l.back)
1898 }
1899
1900 func (l *lst) moveToFront(n *node) *node {
1901 return l.pushFront(l.remove(n))
1902 }
1903
1904 func (l *lst) size() (sz int64) {
1905 for n := l.front; n != nil; n = n.next {
1906 sz += int64(cap(n.b))
1907 }
1908 return
1909 }
1910
1911 func cacheAudit(m map[int64]*node, l *lst) (err error) {
1912 cnt := 0
1913 for h, n := range m {
1914 if g, e := n.h, h; g != e {
1915 return fmt.Errorf("cacheAudit: invalid node handle %d != %d", g, e)
1916 }
1917
1918 if cnt, err = l.audit(n, true); err != nil {
1919 return
1920 }
1921 }
1922
1923 if g, e := cnt, len(m); g != e {
1924 return fmt.Errorf("cacheAudit: invalid cache size %d != %d", g, e)
1925 }
1926
1927 return
1928 }
1929
1930 func (l *lst) audit(n *node, onList bool) (cnt int, err error) {
1931 if !onList && (n.prev != nil || n.next != nil) {
1932 return -1, fmt.Errorf("lst.audit: free node with non nil linkage")
1933 }
1934
1935 if l.front == nil && l.back != nil || l.back == nil && l.front != nil {
1936 return -1, fmt.Errorf("lst.audit: one of .front/.back is nil while the other is non nil")
1937 }
1938
1939 if l.front == l.back && l.front != nil {
1940 x := l.front
1941 if x.prev != nil || x.next != nil {
1942 return -1, fmt.Errorf("lst.audit: single node has non nil linkage")
1943 }
1944
1945 if onList && x != n {
1946 return -1, fmt.Errorf("lst.audit: single node is alien")
1947 }
1948 }
1949
1950 seen := false
1951 var prev *node
1952 x := l.front
1953 for x != nil {
1954 cnt++
1955 if x.prev != prev {
1956 return -1, fmt.Errorf("lst.audit: broken .prev linkage")
1957 }
1958
1959 if x == n {
1960 seen = true
1961 }
1962
1963 prev = x
1964 x = x.next
1965 }
1966
1967 if prev != l.back {
1968 return -1, fmt.Errorf("lst.audit: broken .back linkage")
1969 }
1970
1971 if onList && !seen {
1972 return -1, fmt.Errorf("lst.audit: node missing in list")
1973 }
1974
1975 if !onList && seen {
1976 return -1, fmt.Errorf("lst.audit: node should not be on the list")
1977 }
1978
1979 return
1980 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 package lldb
5
6 import (
7 "bytes"
8 "encoding/hex"
9 "flag"
10 "fmt"
11 "math/rand"
12 "os"
13 "runtime"
14 "sort"
15 "strings"
16 "testing"
17 "time"
18
19 "github.com/cznic/bufs"
20 "github.com/cznic/sortutil"
21 "github.com/cznic/zappy"
22 )
23
24 var (
25 allocRndTestLimit = flag.Uint("lim", 2*maxShort, "Allocator rnd test initial blocks size limit")
26 allocRndTestHardLimit = flag.Uint("hlim", 0, "Allocator rnd test initial blocks size hard limit")
27 testN = flag.Int("N", 128, "Allocator rnd test block count")
28 allocRndDump = flag.Bool("dump", false, "Produce dump files on TestAllocatorRnd crash")
29 oKeep = flag.Bool("keep", false, "do not delete testing DB/WAL (where applicable)")
30 )
31
32 func init() {
33 reallocTestHook = true
34 }
35
36 func mfBytes(f Filer) []byte {
37 var b bytes.Buffer
38 if _, err := f.(*MemFiler).WriteTo(&b); err != nil {
39 panic(err)
40 }
41
42 return b.Bytes()
43 }
44
45 // Paranoid Allocator, automatically verifies whenever possible.
46 type pAllocator struct {
47 *Allocator
48 errors []error
49 logger func(error) bool
50 lastKnownGood *MemFiler
51 lastKnownGoodFLT flt
52 lastOp string
53 stats AllocStats
54 }
55
56 func newPAllocator(f Filer) (*pAllocator, error) {
57 a, err := NewAllocator(f, &Options{})
58 if err != nil {
59 return nil, err
60 }
61
62 r := &pAllocator{Allocator: a, lastKnownGood: NewMemFiler()}
63 r.logger = func(err error) bool {
64 r.errors = append(r.errors, err)
65 return len(r.errors) < 100
66 }
67
68 return r, nil
69 }
70
71 func (a *pAllocator) err() error {
72 var n int
73 if n = len(a.errors); n == 0 {
74 return nil
75 }
76
77 s := make([]string, n)
78 for i, e := range a.errors {
79 s[i] = e.Error()
80 }
81 return fmt.Errorf("\n%s", strings.Join(s, "\n"))
82 }
83
84 func (a *pAllocator) preMortem(s string) {
85 var e error
86 if e := a.lastKnownGood.Truncate(0); e != nil {
87 panic(e)
88 }
89 b := mfBytes(a.Allocator.f)
90 if _, e = a.lastKnownGood.WriteAt(b, 0); e != nil {
91 return
92 }
93 a.lastKnownGoodFLT = a.flt
94 a.lastOp = s
95 }
96
97 func (a *pAllocator) Alloc(b []byte) (handle int64, err error) {
98 if *allocRndDump {
99 a.preMortem("")
100 defer func() { a.lastOp = fmt.Sprintf("Alloc(%d bytes): h %#x", len(b), handle) }()
101 }
102
103 if handle, err = a.Allocator.Alloc(b); err != nil {
104 return
105 }
106
107 if err = a.Allocator.Verify(NewMemFiler(), a.logger, &a.stats); err != nil {
108 err = fmt.Errorf("'%s': %v", err, a.err())
109 return
110 }
111
112 err = a.err()
113 return
114 }
115
116 func (a *pAllocator) Free(handle int64) (err error) {
117 if *allocRndDump {
118 a.preMortem(fmt.Sprintf("Free(h %#x)", handle))
119 }
120
121 if err = a.Allocator.Free(handle); err != nil {
122 return
123 }
124
125 if err = a.Allocator.Verify(NewMemFiler(), a.logger, &a.stats); err != nil {
126 err = fmt.Errorf("'%s': %v", err, a.err())
127 return
128 }
129
130 err = a.err()
131 return
132 }
133
134 func (a *pAllocator) Realloc(handle int64, b []byte) (err error) {
135 if *allocRndDump {
136 a.preMortem(fmt.Sprintf("Realloc(h %#x, %d bytes)", handle, len(b)))
137 }
138
139 if err = a.Allocator.Realloc(handle, b); err != nil {
140 return
141 }
142
143 if err = cacheAudit(a.Allocator.m, &a.Allocator.lru); err != nil {
144 return
145 }
146
147 if err = a.Allocator.Verify(NewMemFiler(), a.logger, &a.stats); err != nil {
148 err = fmt.Errorf("'%s': %v", err, a.err())
149 return
150 }
151
152 err = a.err()
153 return
154 }
155
156 func dump(a *pAllocator, t *testing.T) {
157 m := a.f.(*MemFiler)
158 sz, err := m.Size()
159 if err != nil {
160 t.Fatal(err)
161 }
162
163 t.Logf("MemFiler.Size() == %d(%#x)", sz, sz)
164 if !*allocRndDump {
165 return
166 }
167
168 fn := "good-dump"
169 f, err := os.Create(fn)
170 if err != nil {
171 t.Fatal(err)
172 }
173
174 defer f.Close()
175 sz, err = a.lastKnownGood.WriteTo(f)
176 if err != nil {
177 t.Error(err)
178 return
179 }
180
181 t.Logf("%d(%#x) writen to %q", sz, sz, fn)
182
183 fn = "bad-dump"
184 g, err := os.Create(fn)
185 if err != nil {
186 t.Fatal(err)
187 }
188
189 defer g.Close()
190 sz, err = m.WriteTo(g)
191 if err != nil {
192 t.Error(err)
193 return
194 }
195
196 t.Logf("%d(%#x) writen to %q", sz, sz, fn)
197
198 t.Log("Last known good FLT")
199 for _, slot := range a.lastKnownGoodFLT {
200 if h := slot.head; h != 0 {
201 t.Logf("min %d head %#x off %#x", slot.minSize, h, h2off(h))
202 }
203 }
204
205 t.Log("Current FLT")
206 r := a.flt
207 for _, slot := range r {
208 if h := slot.head; h != 0 {
209 t.Logf("min %d head %#x off %#x", slot.minSize, h, h2off(h))
210 }
211 }
212 t.Logf("Last op: %q", a.lastOp)
213 }
214
215 func init() {
216 if *testN <= 0 {
217 *testN = 1
218 }
219 }
220
221 func TestVerify0(t *testing.T) {
222 // All must fail
223 tab := []string{
224
225 // 0: Reloc, links beyond EOF
226 "" +
227 "fd 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00",
228 // 1: Reloc, links beyond EOF
229 "" +
230 "fd 00 00 00 00 00 00 03 00 00 00 00 00 00 00 00" +
231 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
232 // 2: Reloc, broken target
233 "" +
234 "fd 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
235 // 3: Free block at file tail
236 "" +
237 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe",
238 // 4: Free block at file tail
239 "" +
240 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
241 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe",
242 // 5: Reloc, invalid target 0xfe
243 "" +
244 "fd 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00" +
245 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe" +
246 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
247 // 6: Reloc, invalid target 0xfd
248 "" +
249 "fd 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00" +
250 "fd 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00" +
251 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
252 // 7: Lost free block @ 0x00
253 "" +
254 "fe 00 00 00 00 00 00 02 00 00 00 00 00 00 00 fe" +
255 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
256 // 8: Lost free block @ 0x10
257 "" +
258 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
259 "fe 00 00 00 00 00 00 02 00 00 00 00 00 00 00 fe" +
260 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
261 // 9: Invalid padding
262 "" +
263 "00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
264 // 10: Invalid padding
265 "" +
266 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00",
267 // 11: Invalid padding
268 "" +
269 "01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00",
270 // 12: Invalid padding
271 "" +
272 "01 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00",
273 // 13: Invalid padding
274 "" +
275 "0d 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00",
276 // 14: Invalid CC (tail tag)
277 "" +
278 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02",
279 // 15: Invalid CC (tail tag)
280 "" +
281 "fd 00 00 00 00 00 00 02 00 00 00 00 00 00 00 01",
282 // 16: Cannot decompress
283 "" +
284 "0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01",
285 // 17: Invalid reloc target
286 "" +
287 "fd 00 00 00 00 00 00 03 00 00 00 00 00 00 00 00" +
288 "ff 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00" +
289 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ff" +
290 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
291 // 18: Invalid tail tag @1
292 "" +
293 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
294 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
295 // 19: Invalid size @1
296 "" +
297 "ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
298 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff" +
299 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
300 // 20: Invalid size @1
301 "" +
302 "ff 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00" +
303 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ff" +
304 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
305 // 21: Invalid size @1
306 "" +
307 "ff 00 00 00 00 00 00 04 00 00 00 00 00 00 00 00" +
308 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ff" +
309 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
310 // 22: Invalid .next @1
311 "" +
312 "ff 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00" +
313 "00 00 00 00 00 04 00 00 00 00 00 00 00 00 02 ff" +
314 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
315 // 23: Invalid .prev @1
316 "" +
317 "ff 00 00 00 00 00 00 02 00 00 00 00 00 00 04 00" +
318 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ff" +
319 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
320 // 24: Invalid tail tag @1
321 "" +
322 "ff 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00" +
323 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 fe" +
324 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
325 // 25: Invalid tail size @1
326 "" +
327 "ff 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00" +
328 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff" +
329 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
330 // 26: Invalid tail size @1
331 "" +
332 "ff 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00" +
333 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ff" +
334 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
335 // 27: Invalid tail size @1
336 "" +
337 "ff 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00" +
338 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 ff" +
339 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
340 // 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
341 }
342
343 for i, test := range tab {
344 errors := []error{}
345
346 f := NewMemFiler()
347 b := s2b(test)
348 b = append(make([]byte, fltSz), b...)
349 n := len(b)
350 if n == 0 {
351 t.Fatal(n)
352 }
353
354 if m, err := f.ReadFrom(bytes.NewBuffer(b)); m != int64(n) || err != nil {
355 t.Fatal(m, err)
356 }
357
358 sz, err := f.Size()
359 if err != nil {
360 t.Fatal(err)
361 }
362
363 if g, e := sz, int64(n); g != e {
364 t.Fatal(g, e)
365 }
366
367 a, err := newPAllocator(f)
368 if err != nil {
369 t.Fatal(err)
370 }
371
372 err = a.Verify(
373 NewMemFiler(),
374 func(err error) bool {
375 if err == nil {
376 t.Fatal("nil error")
377 }
378 errors = append(errors, err)
379 return false
380 },
381 nil,
382 )
383 if err == nil {
384 t.Fatal(i, "unexpected success")
385 }
386
387 t.Log(i, err, errors)
388 }
389 }
390
391 func TestVerify1(t *testing.T) {
392 f := NewMemFiler()
393 bitmap := NewMemFiler()
394 if n, err := bitmap.WriteAt([]byte{0}, 0); n != 1 || err != nil {
395 t.Fatal(n, err)
396 }
397
398 a, err := newPAllocator(f)
399 if err != nil {
400 t.Fatal(err)
401 }
402
403 if err := a.Verify(
404 bitmap,
405 func(error) bool {
406 panic("intrnal error")
407 },
408 nil,
409 ); err == nil {
410 t.Fatal("unexpected success")
411 }
412 }
413
414 func repDump(a flt) string {
415 b := []string{}
416 for _, v := range a {
417 if h := v.head; h != 0 {
418 b = append(b, fmt.Sprintf("min:%d, h:%d", v.minSize, h))
419 }
420 }
421 return strings.Join(b, ";")
422 }
423
424 func TestVerify2(t *testing.T) {
425 // All must fail for the fixed (see bellow) FLT.Report()
426 tab := []string{
427
428 // 0: FLT broken linkage (missing free blocks @2,4)
429 "" +
430 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
431 // 1: FLT broken linkage (missing free block @4)
432 "" +
433 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
434 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe" +
435 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
436 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
437 // 2: bad size @4
438 "" +
439 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
440 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe" +
441 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
442 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe" +
443 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
444 // // 3: bad size @4
445 "" +
446 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
447 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 04 fe" +
448 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
449 "ff 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00" +
450 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ff" +
451 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
452 // // 4: bad .next @6 from @2
453 "" +
454 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
455 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 06 fe" +
456 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
457 "ff 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00" +
458 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ff" +
459 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
460 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe" +
461 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
462 // // 5: bad .prev @7
463 "" +
464 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
465 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 07 fe" +
466 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
467 "ff 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00" +
468 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ff" +
469 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
470 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe" +
471 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
472 // // 6: bad .next @7
473 "" +
474 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
475 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 07 fe" +
476 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
477 "ff 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00" +
478 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ff" +
479 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
480 "fe 00 00 00 00 00 00 02 00 00 00 00 00 00 07 fe" +
481 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
482 // // 7: bad .next @5
483 "" +
484 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
485 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 07 fe" +
486 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
487 "ff 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00" +
488 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ff" +
489 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
490 "fe 00 00 00 00 00 00 02 00 00 00 00 00 00 01 fe" +
491 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
492 // // 8: bad chaining
493 "" +
494 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
495 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 07 fe" +
496 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
497 "ff 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00" +
498 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ff" +
499 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
500 "fe 00 00 00 00 00 00 02 00 00 00 00 00 00 01 fe" +
501 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
502 // // 9: lost free block @8
503 "" +
504 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
505 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 0f fe" +
506 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
507 "ff 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00" +
508 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ff" +
509 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
510 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
511 "fe 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe" +
512 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
513 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
514 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
515 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
516 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
517 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" +
518 "fe 00 00 00 00 00 00 02 00 00 00 00 00 00 00 fe" +
519 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
520 // 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
521 }
522
523 for i, test := range tab {
524 errors := []error{}
525
526 f := NewMemFiler()
527 b := s2b(test)
528 b = append(make([]byte, fltSz), b...)
529 n := len(b)
530 if n == 0 {
531 t.Fatal(n)
532 }
533
534 if m, err := f.ReadFrom(bytes.NewBuffer(b)); m != int64(n) || err != nil {
535 t.Fatal(m, err)
536 }
537
538 sz, err := f.Size()
539 if err != nil {
540 t.Fatal(err)
541 }
542
543 if g, e := sz, int64(n); g != e {
544 t.Fatal(g, e)
545 }
546
547 a, err := newPAllocator(f)
548 if err != nil {
549 t.Fatal(err)
550 }
551
552 a.flt.setHead(2, 1, a.f)
553 a.flt.setHead(4, 2, a.f)
554 err = a.Verify(
555 NewMemFiler(),
556 func(err error) bool {
557 if err == nil {
558 t.Fatal("nil error")
559 }
560 t.Log(i, "logged: ", err)
561 errors = append(errors, err)
562 return true
563 },
564 nil,
565 )
566 if err == nil {
567 t.Fatal(i, "unexpected success")
568 }
569
570 t.Log(i, err, errors)
571 }
572 }
573
574 // Allocation in an empty DB.
575 func TestAllocatorAlloc0(t *testing.T) {
576 tab := []struct {
577 h int64
578 b, f, fc string
579 }{
580 {1, // len 0
581 "" +
582 "",
583 "" +
584 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
585 "" +
586 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"},
587 {1, // len 1
588 "" +
589 "42",
590 "" +
591 "01 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
592 "" +
593 "01 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00"},
594 {1, // max single atom, not compressible
595 "" +
596 "01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e",
597 "" +
598 "0e 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 00",
599 "" +
600 "0e 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 00"},
601 {1, // max single atom, compressible, but not eligible for it
602 "" +
603 "01 02 03 04 05 06 07 08 99 01 02 03 04 05",
604 "" +
605 "0e 01 02 03 04 05 06 07 08 99 01 02 03 04 05 00",
606 "" +
607 "0e 01 02 03 04 05 06 07 08 99 01 02 03 04 05 00"},
608 {1, // > 1 atom, not compressible
609 "" +
610 "01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f",
611 "" +
612 "0f 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
613 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
614 "" +
615 "0f 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
616 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"},
617 {1, // > 1 atom, compressible
618 "" +
619 "01 02 03 04 05 06 07 08 99 01 02 03 04 05 06 07" +
620 "08",
621 "" +
622 "11 01 02 03 04 05 06 07 08 99 01 02 03 04 05 06" +
623 "07 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
624 "" +
625 "0e 11 12 01 02 03 04 05 06 07 08 99 01 0d 09 01"},
626 {1, // longest short
627 "" +
628 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
629 "10 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
630 "20 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
631 "30 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
632 "40 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
633 "50 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
634 "60 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
635 "70 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
636 "80 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
637 "90 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
638 "a0 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
639 "b0 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
640 "c0 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
641 "d0 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
642 "e0 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
643 "f0 01 02 03 04 05 06 07 08 09 0a",
644 "" +
645 "" +
646 "fb 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e" +
647 "0f 10 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e" +
648 "0f 20 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e" +
649 "0f 30 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e" +
650 "0f 40 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e" +
651 "0f 50 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e" +
652 "0f 60 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e" +
653 "0f 70 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e" +
654 "0f 80 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e" +
655 "0f 90 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e" +
656 "0f a0 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e" +
657 "0f b0 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e" +
658 "0f c0 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e" +
659 "0f d0 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e" +
660 "0f e0 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e" +
661 "0f f0 01 02 03 04 05 06 07 08 09 0a 00 00 00 00",
662 "" +
663 "" +
664 "4e fb 01 20 00 01 02 03 04 05 06 07 08 09 0a 0b" +
665 "0c 0d 0e 0f 10 1d 10 00 20 1d 10 00 30 1d 10 00" +
666 "40 1d 10 00 50 1d 10 00 60 1d 10 00 70 1d 10 00" +
667 "80 1d 10 00 90 1d 10 00 a0 1d 10 00 b0 1d 10 00" +
668 "c0 1d 10 00 d0 1d 10 00 e0 1d 10 00 f0 13 10 01"},
669
670 {1, // shortest long
671 "" +
672 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
673 "10 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
674 "20 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
675 "30 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
676 "40 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
677 "50 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
678 "60 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
679 "70 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
680 "80 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
681 "90 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
682 "a0 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
683 "b0 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
684 "c0 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
685 "d0 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
686 "e0 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" +
687 "f0 01 02 03 04 05 06 07 08 09 0a 0b",
688 "" +
689 "" +
690 "fc 00 fc 00 01 02 03 04 05 06 07 08 09 0a 0b 0c" +
691 "0d 0e 0f 10 01 02 03 04 05 06 07 08 09 0a 0b 0c" +
692 "0d 0e 0f 20 01 02 03 04 05 06 07 08 09 0a 0b 0c" +
693 "0d 0e 0f 30 01 02 03 04 05 06 07 08 09 0a 0b 0c" +
694 "0d 0e 0f 40 01 02 03 04 05 06 07 08 09 0a 0b 0c" +
695 "0d 0e 0f 50 01 02 03 04 05 06 07 08 09 0a 0b 0c" +
696 "0d 0e 0f 60 01 02 03 04 05 06 07 08 09 0a 0b 0c" +
697 "0d 0e 0f 70 01 02 03 04 05 06 07 08 09 0a 0b 0c" +
698 "0d 0e 0f 80 01 02 03 04 05 06 07 08 09 0a 0b 0c" +
699 "0d 0e 0f 90 01 02 03 04 05 06 07 08 09 0a 0b 0c" +
700 "0d 0e 0f a0 01 02 03 04 05 06 07 08 09 0a 0b 0c" +
701 "0d 0e 0f b0 01 02 03 04 05 06 07 08 09 0a 0b 0c" +
702 "0d 0e 0f c0 01 02 03 04 05 06 07 08 09 0a 0b 0c" +
703 "0d 0e 0f d0 01 02 03 04 05 06 07 08 09 0a 0b 0c" +
704 "0d 0e 0f e0 01 02 03 04 05 06 07 08 09 0a 0b 0c" +
705 "0d 0e 0f f0 01 02 03 04 05 06 07 08 09 0a 0b 00",
706 "" +
707 "" +
708 "4e fc 01 20 00 01 02 03 04 05 06 07 08 09 0a 0b" +
709 "0c 0d 0e 0f 10 1d 10 00 20 1d 10 00 30 1d 10 00" +
710 "40 1d 10 00 50 1d 10 00 60 1d 10 00 70 1d 10 00" +
711 "80 1d 10 00 90 1d 10 00 a0 1d 10 00 b0 1d 10 00" +
712 "c0 1d 10 00 d0 1d 10 00 e0 1d 10 00 f0 15 10 01"},
713 }
714
715 for i, test := range tab {
716 f := func(compress bool, e []byte) {
717 f := NewMemFiler()
718 a, err := newPAllocator(f)
719 if err != nil {
720 t.Fatal(err)
721 }
722
723 a.Compress = compress
724 h, err := a.Alloc(s2b(test.b))
725 if err != nil {
726 t.Fatalf("%d %#v\n%s", i, err, hex.Dump(mfBytes(f)))
727 }
728
729 if g, e := h, test.h; g != e {
730 t.Fatal(i, g, e)
731 }
732
733 g := mfBytes(f)
734 if g = g[fltSz:]; !bytes.Equal(g, e) {
735 t.Fatalf("\ni: %d compress: %t\ng:\n%se:\n%s", i, compress, hex.Dump(g), hex.Dump(e))
736 }
737 }
738 f(false, s2b(test.f))
739 f(true, s2b(test.fc))
740 }
741 }
742
743 func TestAllocatorMakeUsedBlock(t *testing.T) {
744 f := NewMemFiler()
745 a, err := NewAllocator(f, &Options{})
746 if err != nil {
747 t.Fatal(err)
748 }
749
750 dst := bufs.GCache.Get(zappy.MaxEncodedLen(maxRq + 1))
751 defer bufs.GCache.Put(dst)
752 if _, _, _, err := a.makeUsedBlock(dst, make([]byte, maxRq)); err != nil {
753 t.Fatal(err)
754 }
755
756 if _, _, _, err := a.makeUsedBlock(dst, make([]byte, maxRq+1)); err == nil {
757 t.Fatal("unexpected success")
758 }
759 }
760
761 func stableRef(m map[int64][]byte) (r []struct {
762 h int64
763 b []byte
764 }) {
765 a := make(sortutil.Int64Slice, 0, len(m))
766 for k := range m {
767 a = append(a, k)
768 }
769 sort.Sort(a)
770 for _, v := range a {
771 r = append(r, struct {
772 h int64
773 b []byte
774 }{v, m[v]})
775 }
776 return
777 }
778
779 func TestAllocatorRnd(t *testing.T) {
780 N := *testN
781
782 for cc := 0; cc < 2; cc++ {
783 rng := rand.New(rand.NewSource(42))
784 f := NewMemFiler()
785 a, err := newPAllocator(f)
786 if err != nil {
787 t.Fatal(err)
788 }
789
790 balance := 0
791
792 bad := func() bool {
793 if a.Compress {
794 return false
795 }
796
797 actual := a.stats.TotalAtoms - a.stats.FreeAtoms - a.stats.Relocations
798 if int64(balance) != actual {
799 t.Logf("balance: %d, actual %d\n%#v", balance, actual, a.stats)
800 return true
801 }
802
803 return false
804 }
805
806 if cc != 0 {
807 a.Compress = true
808 }
809 ref := map[int64][]byte{}
810
811 for pass := 0; pass < 2; pass++ {
812
813 // A) Alloc N blocks
814 for i := 0; i < N; i++ {
815 rq := rng.Int31n(int32(*allocRndTestLimit))
816 if rq%127 == 0 {
817 rq = 3 * maxRq / 4
818 }
819 if rq%11 == 0 {
820 rq %= 23
821 }
822 if hl := *allocRndTestHardLimit; hl != 0 {
823 rq = rq % int32(hl)
824 }
825 b := make([]byte, rq)
826 for j := range b {
827 b[j] = byte(rng.Int())
828 }
829 if rq > 300 {
830 for i := 100; i < 200; i++ {
831 b[i] = 'A' // give compression a chance
832 }
833 }
834
835 balance += n2atoms(len(b))
836 h, err := a.Alloc(b)
837 if err != nil || bad() {
838 dump(a, t)
839 t.Fatalf(
840 "A) N %d, kind %d, pass %d, i:%d, len(b):%d(%#x), err %v",
841 N, 0, pass, i, len(b), len(b), err,
842 )
843 }
844
845 ref[h] = b
846 }
847
848 var rb []byte
849
850 // B) Check them back
851 for h, wb := range ref {
852 if rb, err = a.Get(rb, h); err != nil {
853 dump(a, t)
854 t.Fatal("B)", err)
855 }
856
857 if !bytes.Equal(rb, wb) {
858 dump(a, t)
859 t.Fatalf("B) h %d", h)
860 }
861 }
862
863 nf := 0
864 // C) Free every third block
865 for _, v := range stableRef(ref) {
866 h, b := v.h, v.b
867 if rng.Int()%3 != 0 {
868 continue
869 }
870
871 balance -= n2atoms(len(b))
872 if err = a.Free(h); err != nil || bad() {
873 dump(a, t)
874 t.Fatal(err)
875 }
876
877 delete(ref, h)
878 nf++
879 }
880
881 // D) Check them back
882 for h, wb := range ref {
883 if rb, err = a.Get(rb, h); err != nil {
884 dump(a, t)
885 t.Fatal("D)", err)
886 }
887
888 if !bytes.Equal(rb, wb) {
889 dump(a, t)
890 t.Fatalf("D) h %d", h)
891 }
892 }
893
894 // E) Resize every block remaining
895 for _, v := range stableRef(ref) {
896 h, wb := v.h, append([]byte(nil), v.b...)
897 len0 := len(wb)
898 switch rng.Int() & 1 {
899 case 0:
900 wb = wb[:len(wb)*3/4]
901 case 1:
902 wb = append(wb, wb...)
903 }
904 if len(wb) > maxRq {
905 wb = wb[:maxRq]
906 }
907
908 for j := range wb {
909 wb[j] = byte(rng.Int())
910 }
911 if len(wb) > 300 {
912 for i := 100; i < 200; i++ {
913 wb[i] = 'D' // give compression a chance
914 }
915 }
916 a0, a1 := n2atoms(len0), n2atoms(len(wb))
917 balance = balance - a0 + a1
918 if err := a.Realloc(h, wb); err != nil || bad() {
919 dump(a, t)
920 t.Fatalf(
921 "D) h:%#x, len(b):%#4x, len(wb): %#x, err %v",
922 h, len0, len(wb), err,
923 )
924 }
925
926 if err = cacheAudit(a.m, &a.lru); err != nil {
927 t.Fatal(err)
928 }
929
930 ref[h] = wb
931 }
932
933 // F) Check them back
934 for h, wb := range ref {
935 if rb, err = a.Get(rb, h); err != nil {
936 dump(a, t)
937 t.Fatal("E)", err)
938 }
939
940 if !bytes.Equal(rb, wb) {
941 dump(a, t)
942 t.Fatalf("E) h %d", h)
943 }
944 }
945 }
946
947 if cc == 0 {
948 sz, err := f.Size()
949 if err != nil {
950 t.Fatal(err)
951 }
952
953 t.Logf(
954 "kind %d, AllocAtoms %7d, AllocBytes %7d, FreeAtoms %7d, Relocations %7d, TotalAtoms %7d, f.Size %7d, space eff %.2f%%",
955 0, a.stats.AllocAtoms, a.stats.AllocBytes, a.stats.FreeAtoms, a.stats.Relocations, a.stats.TotalAtoms, sz, 100*float64(a.stats.AllocBytes)/float64(sz),
956 )
957 }
958 // Free everything
959 for h, b := range ref {
960 balance -= n2atoms(len(b))
961 if err = a.Free(h); err != nil || bad() {
962 dump(a, t)
963 t.Fatal(err)
964 }
965 }
966
967 sz, err := a.f.Size()
968 if err != nil {
969 t.Fatal(err)
970 }
971
972 if g, e := sz, int64(fltSz); g != e {
973 dump(a, t)
974 t.Fatal(g, e)
975 }
976 }
977 }
978
979 func TestRollbackAllocator(t *testing.T) {
980 f := NewMemFiler()
981 var r *RollbackFiler
982 r, err := NewRollbackFiler(f,
983 func(sz int64) (err error) {
984 if err = f.Truncate(sz); err != nil {
985 return err
986 }
987
988 return f.Sync()
989 },
990 f,
991 )
992 if err != nil {
993 t.Fatal(err)
994 }
995
996 if err := r.BeginUpdate(); err != nil { // BeginUpdate 0->1
997 t.Fatal(err)
998 }
999
1000 a, err := NewAllocator(r, &Options{})
1001 if err != nil {
1002 t.Fatal(err)
1003 }
1004
1005 h, err := a.Alloc(nil)
1006 if err != nil {
1007 t.Fatal(err)
1008 }
1009
1010 if h != 1 {
1011 t.Fatal(h)
1012 }
1013
1014 // | 1 |
1015
1016 h, err = a.Alloc(nil)
1017 if err != nil {
1018 t.Fatal(err)
1019 }
1020
1021 if h != 2 {
1022 t.Fatal(h)
1023 }
1024
1025 // | 1 | 2 |
1026 h, err = a.Alloc(nil)
1027 if err != nil {
1028 t.Fatal(err)
1029 }
1030
1031 if h != 3 {
1032 t.Fatal(h)
1033 }
1034
1035 // | 1 | 2 | 3 |
1036 if err = a.Free(2); err != nil {
1037 t.Fatal(err)
1038 }
1039
1040 // | 1 | free | 3 |
1041 if err := r.BeginUpdate(); err != nil { // BeginUpdate 1->2
1042 t.Fatal(err)
1043 }
1044
1045 h, err = a.Alloc(nil)
1046 if err != nil {
1047 t.Fatal(err)
1048 }
1049
1050 if h != 2 {
1051 t.Fatal(h)
1052 }
1053
1054 // | 1 | 2 | 3 |
1055 if err := r.Rollback(); err != nil { // Rollback 2->1
1056 t.Fatal(err)
1057 }
1058
1059 // | 1 | free | 3 |
1060 h, err = a.Alloc(nil)
1061 if err != nil {
1062 t.Fatal(err)
1063 }
1064
1065 if h != 2 {
1066 t.Fatal(h)
1067 }
1068
1069 // | 1 | 2 | 3 |
1070 if err := a.Verify(NewMemFiler(), nil, nil); err != nil {
1071 t.Fatal(err)
1072 }
1073 }
1074
1075 func benchmarkAllocatorAlloc(b *testing.B, f Filer, sz int) {
1076 if err := f.BeginUpdate(); err != nil {
1077 b.Error(err)
1078 return
1079 }
1080
1081 a, err := NewAllocator(f, &Options{})
1082 if err != nil {
1083 b.Error(err)
1084 return
1085 }
1086
1087 if err = f.EndUpdate(); err != nil {
1088 b.Error(err)
1089 return
1090 }
1091
1092 v := make([]byte, sz)
1093 runtime.GC()
1094 b.ResetTimer()
1095 for i := 0; i < b.N; i++ {
1096 if err = f.BeginUpdate(); err != nil {
1097 b.Error(err)
1098 return
1099 }
1100
1101 if h, err := a.Alloc(v); h <= 0 || err != nil {
1102 f.EndUpdate()
1103 b.Error(h, err)
1104 return
1105 }
1106
1107 if err = f.EndUpdate(); err != nil {
1108 b.Error(err)
1109 return
1110 }
1111 }
1112 }
1113
1114 func benchmarkAllocatorAllocMemFiler(b *testing.B, sz int) {
1115 f := NewMemFiler()
1116 benchmarkAllocatorAlloc(b, f, sz)
1117 }
1118
1119 func BenchmarkAllocatorAllocMemFiler1e0(b *testing.B) {
1120 benchmarkAllocatorAllocMemFiler(b, 0)
1121 }
1122
1123 func BenchmarkAllocatorAllocMemFiler1e1(b *testing.B) {
1124 benchmarkAllocatorAllocMemFiler(b, 1e1)
1125 }
1126
1127 func BenchmarkAllocatorAllocMemFiler1e2(b *testing.B) {
1128 benchmarkAllocatorAllocMemFiler(b, 1e2)
1129 }
1130
1131 func BenchmarkAllocatorAllocMemFiler1e3(b *testing.B) {
1132 benchmarkAllocatorAllocMemFiler(b, 1e3)
1133 }
1134
1135 func benchmarkAllocatorAllocSimpleFileFiler(b *testing.B, sz int) {
1136 dir, testDbName := temp()
1137 defer os.RemoveAll(dir)
1138
1139 f, err := os.OpenFile(testDbName, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1140 if err != nil {
1141 b.Fatal(err)
1142 }
1143
1144 defer f.Close()
1145
1146 benchmarkAllocatorAlloc(b, NewSimpleFileFiler(f), sz)
1147 }
1148
1149 func BenchmarkAllocatorAllocSimpleFileFiler0(b *testing.B) {
1150 benchmarkAllocatorAllocSimpleFileFiler(b, 0)
1151 }
1152
1153 func BenchmarkAllocatorAllocSimpleFileFiler1e1(b *testing.B) {
1154 benchmarkAllocatorAllocSimpleFileFiler(b, 1e1)
1155 }
1156
1157 func BenchmarkAllocatorAllocSimpleFileFiler1e2(b *testing.B) {
1158 benchmarkAllocatorAllocSimpleFileFiler(b, 1e2)
1159 }
1160
1161 func BenchmarkAllocatorAllocSimpleFileFiler1e3(b *testing.B) {
1162 benchmarkAllocatorAllocSimpleFileFiler(b, 1e3)
1163 }
1164
1165 func benchmarkAllocatorAllocRollbackFiler(b *testing.B, sz int) {
1166 dir, testDbName := temp()
1167 defer os.RemoveAll(dir)
1168
1169 f, err := os.OpenFile(testDbName, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1170 if err != nil {
1171 b.Fatal(err)
1172 }
1173
1174 defer f.Close()
1175
1176 g := NewSimpleFileFiler(f)
1177 var filer *RollbackFiler
1178 if filer, err = NewRollbackFiler(
1179 g,
1180 func(sz int64) error {
1181 if err = g.Truncate(sz); err != nil {
1182 return err
1183 }
1184
1185 return g.Sync()
1186 },
1187 g,
1188 ); err != nil {
1189 b.Error(err)
1190 return
1191 }
1192
1193 benchmarkAllocatorAlloc(b, filer, sz)
1194 }
1195
1196 func BenchmarkAllocatorAllocRollbackFiler0(b *testing.B) {
1197 benchmarkAllocatorAllocRollbackFiler(b, 0)
1198 }
1199
1200 func BenchmarkAllocatorAllocRollbackFiler1e1(b *testing.B) {
1201 benchmarkAllocatorAllocRollbackFiler(b, 1e1)
1202 }
1203
1204 func BenchmarkAllocatorAllocRollbackFiler1e2(b *testing.B) {
1205 benchmarkAllocatorAllocRollbackFiler(b, 1e2)
1206 }
1207
1208 func BenchmarkAllocatorAllocRollbackFiler1e3(b *testing.B) {
1209 benchmarkAllocatorAllocRollbackFiler(b, 1e3)
1210 }
1211
1212 func benchmarkAllocatorAllocACIDFiler(b *testing.B, sz int) {
1213 dir, testDbName := temp()
1214 defer os.RemoveAll(dir)
1215
1216 f, err := os.OpenFile(testDbName, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1217 if err != nil {
1218 b.Fatal(err)
1219 }
1220
1221 defer f.Close()
1222
1223 wal, err := os.OpenFile(testDbName+".wal", os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1224 if err != nil {
1225 b.Fatal(err)
1226 }
1227
1228 defer wal.Close()
1229
1230 filer, err := NewACIDFiler(NewSimpleFileFiler(f), wal)
1231 if err != nil {
1232 b.Error(err)
1233 return
1234 }
1235
1236 benchmarkAllocatorAlloc(b, filer, sz)
1237 }
1238
1239 func BenchmarkAllocatorAllocACIDFiler0(b *testing.B) {
1240 benchmarkAllocatorAllocACIDFiler(b, 0)
1241 }
1242
1243 func BenchmarkAllocatorAllocACIDFiler1e1(b *testing.B) {
1244 benchmarkAllocatorAllocACIDFiler(b, 1e1)
1245 }
1246
1247 func BenchmarkAllocatorAllocACIDFiler1e2(b *testing.B) {
1248 benchmarkAllocatorAllocACIDFiler(b, 1e2)
1249 }
1250
1251 func BenchmarkAllocatorAllocACIDFiler1e3(b *testing.B) {
1252 benchmarkAllocatorAllocACIDFiler(b, 1e3)
1253 }
1254
1255 func benchmarkAllocatorRndFree(b *testing.B, f Filer, sz int) {
1256 if err := f.BeginUpdate(); err != nil {
1257 b.Error(err)
1258 return
1259 }
1260
1261 a, err := NewAllocator(f, &Options{})
1262 if err != nil {
1263 b.Error(err)
1264 return
1265 }
1266
1267 if err = f.EndUpdate(); err != nil {
1268 b.Error(err)
1269 return
1270 }
1271
1272 v := make([]byte, sz)
1273 ref := map[int64]struct{}{}
1274 for i := 0; i < b.N; i++ {
1275 if err = f.BeginUpdate(); err != nil {
1276 b.Error(err)
1277 return
1278 }
1279
1280 h, err := a.Alloc(v)
1281 if h <= 0 || err != nil {
1282 f.EndUpdate()
1283 b.Error(h, err)
1284 return
1285 }
1286
1287 ref[h] = struct{}{}
1288
1289 if err = f.EndUpdate(); err != nil {
1290 b.Error(err)
1291 return
1292 }
1293 }
1294 runtime.GC()
1295 b.ResetTimer()
1296 for h := range ref {
1297 if err = f.BeginUpdate(); err != nil {
1298 b.Error(err)
1299 return
1300 }
1301
1302 if err = a.Free(h); err != nil {
1303 f.EndUpdate()
1304 b.Error(h, err)
1305 return
1306 }
1307
1308 if err = f.EndUpdate(); err != nil {
1309 b.Error(err)
1310 return
1311 }
1312 }
1313 }
1314
1315 func benchmarkAllocatorRndFreeMemFiler(b *testing.B, sz int) {
1316 f := NewMemFiler()
1317 benchmarkAllocatorRndFree(b, f, sz)
1318 }
1319
1320 func BenchmarkAllocatorRndFreeMemFiler0(b *testing.B) {
1321 benchmarkAllocatorRndFreeMemFiler(b, 0)
1322 }
1323
1324 func BenchmarkAllocatorRndFreeMemFiler1e1(b *testing.B) {
1325 benchmarkAllocatorRndFreeMemFiler(b, 1e1)
1326 }
1327
1328 func BenchmarkAllocatorRndFreeMemFiler1e2(b *testing.B) {
1329 benchmarkAllocatorRndFreeMemFiler(b, 1e2)
1330 }
1331
1332 func BenchmarkAllocatorRndFreeMemFiler1e3(b *testing.B) {
1333 benchmarkAllocatorRndFreeMemFiler(b, 1e3)
1334 }
1335
1336 func benchmarkAllocatorRndFreeSimpleFileFiler(b *testing.B, sz int) {
1337 dir, testDbName := temp()
1338 defer os.RemoveAll(dir)
1339
1340 f, err := os.OpenFile(testDbName, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1341 if err != nil {
1342 b.Fatal(err)
1343 }
1344
1345 defer f.Close()
1346
1347 benchmarkAllocatorRndFree(b, NewSimpleFileFiler(f), sz)
1348 }
1349
1350 func BenchmarkAllocatorRndFreeSimpleFileFiler0(b *testing.B) {
1351 benchmarkAllocatorRndFreeSimpleFileFiler(b, 0)
1352 }
1353
1354 func BenchmarkAllocatorRndFreeSimpleFileFiler1e1(b *testing.B) {
1355 benchmarkAllocatorRndFreeSimpleFileFiler(b, 1e1)
1356 }
1357
1358 func BenchmarkAllocatorRndFreeSimpleFileFiler1e2(b *testing.B) {
1359 benchmarkAllocatorRndFreeSimpleFileFiler(b, 1e2)
1360 }
1361
1362 func BenchmarkAllocatorRndFreeSimpleFileFiler1e3(b *testing.B) {
1363 benchmarkAllocatorRndFreeSimpleFileFiler(b, 1e3)
1364 }
1365
1366 func benchmarkAllocatorRndFreeRollbackFiler(b *testing.B, sz int) {
1367 dir, testDbName := temp()
1368 defer os.RemoveAll(dir)
1369
1370 f, err := os.OpenFile(testDbName, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1371 if err != nil {
1372 b.Fatal(err)
1373 }
1374
1375 defer f.Close()
1376
1377 g := NewSimpleFileFiler(f)
1378 var filer *RollbackFiler
1379 if filer, err = NewRollbackFiler(
1380 g,
1381 func(sz int64) error {
1382 if err = g.Truncate(sz); err != nil {
1383 return err
1384 }
1385
1386 return g.Sync()
1387 },
1388 g,
1389 ); err != nil {
1390 b.Error(err)
1391 return
1392 }
1393
1394 benchmarkAllocatorRndFree(b, filer, sz)
1395 }
1396
1397 func BenchmarkAllocatorRndFreeRollbackFiler0(b *testing.B) {
1398 benchmarkAllocatorRndFreeRollbackFiler(b, 0)
1399 }
1400
1401 func BenchmarkAllocatorRndFreeRollbackFiler1e1(b *testing.B) {
1402 benchmarkAllocatorRndFreeRollbackFiler(b, 1e1)
1403 }
1404
1405 func BenchmarkAllocatorRndFreeRollbackFiler1e2(b *testing.B) {
1406 benchmarkAllocatorRndFreeRollbackFiler(b, 1e2)
1407 }
1408
1409 func BenchmarkAllocatorRndFreeRollbackFiler1e3(b *testing.B) {
1410 benchmarkAllocatorRndFreeRollbackFiler(b, 1e3)
1411 }
1412
1413 func benchmarkAllocatorRndFreeACIDFiler(b *testing.B, sz int) {
1414 dir, testDbName := temp()
1415 defer os.RemoveAll(dir)
1416
1417 f, err := os.OpenFile(testDbName, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1418 if err != nil {
1419 b.Fatal(err)
1420 }
1421
1422 defer f.Close()
1423
1424 wal, err := os.OpenFile(testDbName+".wal", os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1425 if err != nil {
1426 b.Fatal(err)
1427 }
1428
1429 defer wal.Close()
1430
1431 filer, err := NewACIDFiler(NewSimpleFileFiler(f), wal)
1432 if err != nil {
1433 b.Error(err)
1434 return
1435 }
1436
1437 benchmarkAllocatorRndFree(b, filer, sz)
1438 }
1439
1440 func BenchmarkAllocatorRndFreeACIDFiler0(b *testing.B) {
1441 benchmarkAllocatorRndFreeACIDFiler(b, 0)
1442 }
1443
1444 func BenchmarkAllocatorRndFreeACIDFiler1e1(b *testing.B) {
1445 benchmarkAllocatorRndFreeACIDFiler(b, 1e1)
1446 }
1447
1448 func BenchmarkAllocatorRndFreeACIDFiler1e2(b *testing.B) {
1449 benchmarkAllocatorRndFreeACIDFiler(b, 1e2)
1450 }
1451
1452 func BenchmarkAllocatorRndFreeACIDFiler1e3(b *testing.B) {
1453 benchmarkAllocatorRndFreeACIDFiler(b, 1e3)
1454 }
1455
1456 func benchmarkAllocatorRndGet(b *testing.B, f Filer, sz int) {
1457 if err := f.BeginUpdate(); err != nil {
1458 b.Error(err)
1459 return
1460 }
1461
1462 a, err := NewAllocator(f, &Options{})
1463 if err != nil {
1464 b.Error(err)
1465 return
1466 }
1467
1468 if err = f.EndUpdate(); err != nil {
1469 b.Error(err)
1470 return
1471 }
1472
1473 v := make([]byte, sz)
1474 ref := map[int64]struct{}{}
1475 if err = f.BeginUpdate(); err != nil {
1476 b.Error(err)
1477 return
1478 }
1479
1480 for i := 0; i < b.N; i++ {
1481 h, err := a.Alloc(v)
1482 if h <= 0 || err != nil {
1483 f.EndUpdate()
1484 b.Error(h, err)
1485 return
1486 }
1487
1488 ref[h] = struct{}{}
1489
1490 }
1491 if err = f.EndUpdate(); err != nil {
1492 b.Error(err)
1493 return
1494 }
1495
1496 runtime.GC()
1497 b.ResetTimer()
1498 for h := range ref {
1499 if err = f.BeginUpdate(); err != nil {
1500 b.Error(err)
1501 return
1502 }
1503
1504 if _, err = a.Get(v, h); err != nil {
1505 f.EndUpdate()
1506 b.Error(h, err)
1507 return
1508 }
1509
1510 if err = f.EndUpdate(); err != nil {
1511 b.Error(err)
1512 return
1513 }
1514 }
1515 }
1516
1517 func benchmarkAllocatorRndGetMemFiler(b *testing.B, sz int) {
1518 f := NewMemFiler()
1519 benchmarkAllocatorRndGet(b, f, sz)
1520 }
1521
1522 func BenchmarkAllocatorRndGetMemFiler0(b *testing.B) {
1523 benchmarkAllocatorRndGetMemFiler(b, 0)
1524 }
1525
1526 func BenchmarkAllocatorRndGetMemFiler1e1(b *testing.B) {
1527 benchmarkAllocatorRndGetMemFiler(b, 1e1)
1528 }
1529
1530 func BenchmarkAllocatorRndGetMemFiler1e2(b *testing.B) {
1531 benchmarkAllocatorRndGetMemFiler(b, 1e2)
1532 }
1533
1534 func BenchmarkAllocatorRndGetMemFiler1e3(b *testing.B) {
1535 benchmarkAllocatorRndGetMemFiler(b, 1e3)
1536 }
1537
1538 func benchmarkAllocatorRndGetSimpleFileFiler(b *testing.B, sz int) {
1539 os.Remove(testDbName)
1540 <-time.After(5 * time.Second)
1541 f, err := os.OpenFile(testDbName, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1542 if err != nil {
1543 b.Fatal(err)
1544 }
1545
1546 defer func() {
1547 f.Close()
1548 os.Remove(testDbName)
1549 }()
1550
1551 benchmarkAllocatorRndGet(b, NewSimpleFileFiler(f), sz)
1552 }
1553
1554 func BenchmarkAllocatorRndGetSimpleFileFiler0(b *testing.B) {
1555 benchmarkAllocatorRndGetSimpleFileFiler(b, 0)
1556 }
1557
1558 func BenchmarkAllocatorRndGetSimpleFileFiler1e1(b *testing.B) {
1559 benchmarkAllocatorRndGetSimpleFileFiler(b, 1e1)
1560 }
1561
1562 func BenchmarkAllocatorRndGetSimpleFileFiler1e2(b *testing.B) {
1563 benchmarkAllocatorRndGetSimpleFileFiler(b, 1e2)
1564 }
1565
1566 func BenchmarkAllocatorRndGetSimpleFileFiler1e3(b *testing.B) {
1567 benchmarkAllocatorRndGetSimpleFileFiler(b, 1e3)
1568 }
1569
1570 func benchmarkAllocatorRndGetRollbackFiler(b *testing.B, sz int) {
1571 os.Remove(testDbName)
1572 f, err := os.OpenFile(testDbName, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1573 if err != nil {
1574 b.Fatal(err)
1575 }
1576
1577 defer func() {
1578 f.Close()
1579 os.Remove(testDbName)
1580 }()
1581
1582 g := NewSimpleFileFiler(f)
1583 var filer *RollbackFiler
1584 if filer, err = NewRollbackFiler(
1585 g,
1586 func(sz int64) error {
1587 if err = g.Truncate(sz); err != nil {
1588 return err
1589 }
1590
1591 return g.Sync()
1592 },
1593 g,
1594 ); err != nil {
1595 b.Error(err)
1596 return
1597 }
1598
1599 benchmarkAllocatorRndGet(b, filer, sz)
1600 }
1601
1602 func BenchmarkAllocatorRndGetRollbackFiler0(b *testing.B) {
1603 benchmarkAllocatorRndGetRollbackFiler(b, 0)
1604 }
1605
1606 func BenchmarkAllocatorRndGetRollbackFiler1e1(b *testing.B) {
1607 benchmarkAllocatorRndGetRollbackFiler(b, 1e1)
1608 }
1609
1610 func BenchmarkAllocatorRndGetRollbackFiler1e2(b *testing.B) {
1611 benchmarkAllocatorRndGetRollbackFiler(b, 1e2)
1612 }
1613
1614 func BenchmarkAllocatorRndGetRollbackFiler1e3(b *testing.B) {
1615 benchmarkAllocatorRndGetRollbackFiler(b, 1e3)
1616 }
1617
1618 func benchmarkAllocatorRndGetACIDFiler(b *testing.B, sz int) {
1619 os.Remove(testDbName)
1620 os.Remove(walName)
1621 f, err := os.OpenFile(testDbName, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1622 if err != nil {
1623 b.Fatal(err)
1624 }
1625
1626 defer func() {
1627 f.Close()
1628 os.Remove(testDbName)
1629 }()
1630
1631 wal, err := os.OpenFile(walName, os.O_CREATE|os.O_EXCL|os.O_RDWR, 0600)
1632 if err != nil {
1633 b.Fatal(err)
1634 }
1635
1636 defer func() {
1637 wal.Close()
1638 os.Remove(walName)
1639 }()
1640
1641 filer, err := NewACIDFiler(NewSimpleFileFiler(f), wal)
1642 if err != nil {
1643 b.Error(err)
1644 return
1645 }
1646
1647 benchmarkAllocatorRndGet(b, filer, sz)
1648 }
1649
1650 func BenchmarkAllocatorRndGetACIDFiler0(b *testing.B) {
1651 benchmarkAllocatorRndGetACIDFiler(b, 0)
1652 }
1653
1654 func BenchmarkAllocatorRndGetACIDFiler1e1(b *testing.B) {
1655 benchmarkAllocatorRndGetACIDFiler(b, 1e1)
1656 }
1657
1658 func BenchmarkAllocatorRndGetACIDFiler1e2(b *testing.B) {
1659 benchmarkAllocatorRndGetACIDFiler(b, 1e2)
1660 }
1661
1662 func BenchmarkAllocatorRndGetACIDFiler1e3(b *testing.B) {
1663 benchmarkAllocatorRndGetACIDFiler(b, 1e3)
1664 }
1665
1666 func TestFltFind(t *testing.T) {
1667 var f flt
1668
1669 f.init()
1670 if h := f.find(1); h != 0 {
1671 t.Fatal(h)
1672 }
1673
1674 // [0]
1675 f.init()
1676 f[0].head = 1
1677 if h := f.find(1); h != 1 || f[0].head != 0 {
1678 t.Fatal(h)
1679 }
1680
1681 f.init()
1682 f[0].head = 1
1683 if h := f.find(2); h != 0 || f[0].head == 0 {
1684 t.Fatal(h)
1685 }
1686
1687 // [1]
1688 f.init()
1689 f[1].head = 1
1690 if h := f.find(1); h != 1 || f[1].head != 0 {
1691 t.Fatal("\n", f, h)
1692 }
1693
1694 f.init()
1695 f[1].head = 1
1696 if h := f.find(2); h != 1 || f[1].head != 0 {
1697 t.Fatal(f, h)
1698 }
1699
1700 f.init()
1701 f[1].head = 1
1702 if h := f.find(3); h != 0 || f[1].head == 0 {
1703 t.Fatal(h)
1704 }
1705
1706 // [2]
1707 f.init()
1708 f[2].head = 1
1709 if h := f.find(1); h != 1 || f[2].head != 0 {
1710 t.Fatal(h)
1711 }
1712
1713 f.init()
1714 f[2].head = 1
1715 if h := f.find(2); h != 1 || f[2].head != 0 {
1716 t.Fatal(h)
1717 }
1718
1719 f.init()
1720 f[2].head = 1
1721 if h := f.find(3); h != 1 || f[2].head != 0 {
1722 t.Fatal(h)
1723 }
1724
1725 f.init()
1726 f[2].head = 1
1727 if h := f.find(4); h != 1 || f[2].head != 0 {
1728 t.Fatal(h)
1729 }
1730
1731 f.init()
1732 f[2].head = 1
1733 if h := f.find(5); h != 0 || f[2].head == 0 {
1734 t.Fatal(h)
1735 }
1736 }
1737
1738 func TestFltHead(t *testing.T) {
1739 var f flt
1740 f.init()
1741 if h := f.head(1); h != 0 {
1742 t.Fatal(h)
1743 }
1744
1745 // [0]
1746 f.init()
1747 f[0].head = 1
1748 if h := f.head(1); h != 1 {
1749 t.Fatal(h)
1750 }
1751
1752 f.init()
1753 f[0].head = 1
1754 if h := f.head(2); h != 0 {
1755 t.Fatal(h)
1756 }
1757
1758 // [1]
1759 f.init()
1760 f[1].head = 1
1761 if h := f.head(1); h != 0 {
1762 t.Fatal(h)
1763 }
1764
1765 f.init()
1766 f[1].head = 1
1767 if h := f.head(2); h != 1 {
1768 t.Fatal(h)
1769 }
1770
1771 f.init()
1772 f[1].head = 1
1773 if h := f.head(3); h != 1 {
1774 t.Fatal(h)
1775 }
1776
1777 f.init()
1778 f[1].head = 1
1779 if h := f.head(4); h != 0 {
1780 t.Fatal(h)
1781 }
1782
1783 // [2]
1784 f.init()
1785 f[2].head = 1
1786 if h := f.head(1); h != 0 {
1787 t.Fatal(h)
1788 }
1789
1790 f.init()
1791 f[2].head = 1
1792 if h := f.head(2); h != 0 {
1793 t.Fatal(h)
1794 }
1795
1796 f.init()
1797 f[2].head = 1
1798 if h := f.head(3); h != 0 {
1799 t.Fatal(h)
1800 }
1801
1802 f.init()
1803 f[2].head = 1
1804 if h := f.head(4); h != 1 {
1805 t.Fatal(h)
1806 }
1807
1808 f.init()
1809 f[2].head = 1
1810 if h := f.head(5); h != 1 {
1811 t.Fatal(h)
1812 }
1813
1814 f.init()
1815 f[2].head = 1
1816 if h := f.head(6); h != 1 {
1817 t.Fatal(h)
1818 }
1819
1820 f.init()
1821 f[2].head = 1
1822 if h := f.head(7); h != 1 {
1823 t.Fatal(h)
1824 }
1825
1826 f.init()
1827 f[2].head = 1
1828 if h := f.head(8); h != 0 {
1829 t.Fatal(h)
1830 }
1831
1832 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 // An abstraction of file like (persistent) storage with optional (abstracted)
5 // support for structural integrity.
6
7 package lldb
8
9 import (
10 "fmt"
11
12 "github.com/cznic/mathutil"
13 )
14
15 func doubleTrouble(first, second error) error {
16 return fmt.Errorf("%q. Additionally, while attempting to recover (rollback): %q", first, second)
17 }
18
19 // A Filer is a []byte-like model of a file or similar entity. It may
20 // optionally implement support for structural transaction safety. In contrast
21 // to a file stream, a Filer is not sequentially accessible. ReadAt and WriteAt
22 // are always "addressed" by an offset and are assumed to perform atomically.
23 // A Filer is not safe for concurrent access, it's designed for consumption by
24 // the other objects in package, which should use a Filer from one goroutine
25 // only or via a mutex. BeginUpdate, EndUpdate and Rollback must be either all
26 // implemented by a Filer for structural integrity - or they should be all
27 // no-ops; where/if that requirement is relaxed.
28 //
29 // If a Filer wraps another Filer implementation, it usually invokes the same
30 // methods on the "inner" one, after some possible argument translations etc.
31 // If a Filer implements the structural transactions handling methods
32 // (BeginUpdate, EndUpdate and Rollback) as no-ops _and_ wraps another Filer:
33 // it then still MUST invoke those methods on the inner Filer. This is
34 // important for the case where a RollbackFiler exists somewhere down the
35 // chain. It's also important for an Allocator - to know when it must
36 // invalidate its FLT cache.
37 type Filer interface {
38 // BeginUpdate increments the "nesting" counter (initially zero). Every
39 // call to BeginUpdate must be eventually "balanced" by exactly one of
40 // EndUpdate or Rollback. Calls to BeginUpdate may nest.
41 BeginUpdate() error
42
43 // Analogous to os.File.Close().
44 Close() error
45
46 // EndUpdate decrements the "nesting" counter. If it's zero after that
47 // then assume the "storage" has reached structural integrity (after a
48 // batch of partial updates). If a Filer implements some support for
49 // that (write ahead log, journal, etc.) then the appropriate actions
50 // are to be taken for nesting == 0. Invocation of an unbalanced
51 // EndUpdate is an error.
52 EndUpdate() error
53
54 // Analogous to os.File.Name().
55 Name() string
56
57 // PunchHole deallocates space inside a "file" in the byte range
58 // starting at off and continuing for size bytes. The actual hole
59 // created by PunchHole may be smaller than requested. The Filer size
60 // (as reported by `Size()` does not change when hole punching, even
61 // when punching the end of a file off. In contrast to the Linux
62 // implementation of FALLOC_FL_PUNCH_HOLE in `fallocate`(2); a Filer is
63 // free not only to ignore `PunchHole()` (implement it as a nop), but
64 // additionally no guarantees about the content of the hole, when
65 // eventually read back, are required, i.e. any data, not only zeros,
66 // can be read from the "hole", including just anything what was left
67 // there - with all of the possible security problems.
68 PunchHole(off, size int64) error
69
70 // As os.File.ReadAt. Note: `off` is an absolute "file pointer"
71 // address and cannot be negative even when a Filer is a InnerFiler.
72 ReadAt(b []byte, off int64) (n int, err error)
73
74 // Rollback cancels and undoes the innermost pending update level.
75 // Rollback decrements the "nesting" counter. If a Filer implements
76 // some support for keeping structural integrity (write ahead log,
77 // journal, etc.) then the appropriate actions are to be taken.
78 // Invocation of an unbalanced Rollback is an error.
79 Rollback() error
80
81 // Analogous to os.File.FileInfo().Size().
82 Size() (int64, error)
83
84 // Analogous to os.Sync().
85 Sync() (err error)
86
87 // Analogous to os.File.Truncate().
88 Truncate(size int64) error
89
90 // Analogous to os.File.WriteAt(). Note: `off` is an absolute "file
91 // pointer" address and cannot be negative even when a Filer is a
92 // InnerFiler.
93 WriteAt(b []byte, off int64) (n int, err error)
94 }
95
96 var _ Filer = &InnerFiler{} // Ensure InnerFiler is a Filer.
97
98 // A InnerFiler is a Filer with added addressing/size translation.
99 type InnerFiler struct {
100 outer Filer
101 off int64
102 }
103
104 // NewInnerFiler returns a new InnerFiler wrapped by `outer` in a way which
105 // adds `off` to every access.
106 //
107 // For example, considering:
108 //
109 // inner := NewInnerFiler(outer, 10)
110 //
111 // then
112 //
113 // inner.WriteAt([]byte{42}, 4)
114 //
115 // translates to
116 //
117 // outer.WriteAt([]byte{42}, 14)
118 //
119 // But an attempt to emulate
120 //
121 // outer.WriteAt([]byte{17}, 9)
122 //
123 // by
124 //
125 // inner.WriteAt([]byte{17}, -1)
126 //
127 // will fail as the `off` parameter can never be < 0. Also note that
128 //
129 // inner.Size() == outer.Size() - off,
130 //
131 // i.e. `inner` pretends no `outer` exists. Finally, after e.g.
132 //
133 // inner.Truncate(7)
134 // outer.Size() == 17
135 //
136 // will be true.
137 func NewInnerFiler(outer Filer, off int64) *InnerFiler { return &InnerFiler{outer, off} }
138
139 // BeginUpdate implements Filer.
140 func (f *InnerFiler) BeginUpdate() error { return f.outer.BeginUpdate() }
141
142 // Close implements Filer.
143 func (f *InnerFiler) Close() (err error) { return f.outer.Close() }
144
145 // EndUpdate implements Filer.
146 func (f *InnerFiler) EndUpdate() error { return f.outer.EndUpdate() }
147
148 // Name implements Filer.
149 func (f *InnerFiler) Name() string { return f.outer.Name() }
150
151 // PunchHole implements Filer. `off`, `size` must be >= 0.
152 func (f *InnerFiler) PunchHole(off, size int64) error { return f.outer.PunchHole(f.off+off, size) }
153
154 // ReadAt implements Filer. `off` must be >= 0.
155 func (f *InnerFiler) ReadAt(b []byte, off int64) (n int, err error) {
156 if off < 0 {
157 return 0, &ErrINVAL{f.outer.Name() + ":ReadAt invalid off", off}
158 }
159
160 return f.outer.ReadAt(b, f.off+off)
161 }
162
163 // Rollback implements Filer.
164 func (f *InnerFiler) Rollback() error { return f.outer.Rollback() }
165
166 // Size implements Filer.
167 func (f *InnerFiler) Size() (int64, error) {
168 sz, err := f.outer.Size()
169 if err != nil {
170 return 0, err
171 }
172
173 return mathutil.MaxInt64(sz-f.off, 0), nil
174 }
175
176 // Sync() implements Filer.
177 func (f *InnerFiler) Sync() (err error) {
178 return f.outer.Sync()
179 }
180
181 // Truncate implements Filer.
182 func (f *InnerFiler) Truncate(size int64) error { return f.outer.Truncate(size + f.off) }
183
184 // WriteAt implements Filer. `off` must be >= 0.
185 func (f *InnerFiler) WriteAt(b []byte, off int64) (n int, err error) {
186 if off < 0 {
187 return 0, &ErrINVAL{f.outer.Name() + ":WriteAt invalid off", off}
188 }
189
190 return f.outer.WriteAt(b, f.off+off)
191 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 package lldb
5
6 import (
7 "bytes"
8 "encoding/hex"
9 "io/ioutil"
10 "math/rand"
11 "os"
12 "runtime"
13 "testing"
14
15 "github.com/cznic/fileutil"
16 )
17
18 // Bench knobs.
19 const (
20 filerTestChunkSize = 32e3
21 filerTotalSize = 10e6
22 )
23
24 type newFunc func() Filer
25
26 type testFileFiler struct {
27 Filer
28 }
29
30 func (t *testFileFiler) Close() (err error) {
31 n := t.Name()
32 err = t.Filer.Close()
33 if errDel := os.Remove(n); errDel != nil && err == nil {
34 err = errDel
35 }
36 return
37 }
38
39 var (
40 newFileFiler = func() Filer {
41 file, err := ioutil.TempFile("", "lldb-test-file")
42 if err != nil {
43 panic(err)
44 }
45
46 return &testFileFiler{NewSimpleFileFiler(file)}
47 }
48
49 newOSFileFiler = func() Filer {
50 file, err := ioutil.TempFile("", "lldb-test-osfile")
51 if err != nil {
52 panic(err)
53 }
54
55 return &testFileFiler{NewOSFiler(file)}
56 }
57
58 newMemFiler = func() Filer {
59 return NewMemFiler()
60 }
61
62 nwBitFiler = func() Filer {
63 f, err := newBitFiler(NewMemFiler())
64 if err != nil {
65 panic(err)
66 }
67
68 return f
69 }
70
71 newRollbackFiler = func() Filer {
72 f := NewMemFiler()
73
74 var r Filer
75
76 checkpoint := func(sz int64) (err error) {
77 return f.Truncate(sz)
78 }
79
80 r, err := NewRollbackFiler(f, checkpoint, f)
81 if err != nil {
82 panic(err)
83 }
84
85 return r
86 }
87 )
88
89 func TestFilerNesting(t *testing.T) {
90 testFilerNesting(t, newFileFiler)
91 testFilerNesting(t, newOSFileFiler)
92 testFilerNesting(t, newMemFiler)
93 testFilerNesting(t, newRollbackFiler)
94 }
95
96 func testFilerNesting(t *testing.T, nf newFunc) {
97 // Check {Create, Close} works.
98 f := nf()
99 t.Log(f.Name())
100 if err := f.Close(); err != nil {
101 t.Fatal(err)
102 }
103
104 // Check {Create, EndUpdate} doesn't work.
105 f = nf()
106 t.Log(f.Name())
107 if err := f.EndUpdate(); err == nil {
108 f.Close()
109 t.Fatal("unexpected success")
110 }
111
112 if err := f.Close(); err != nil {
113 t.Fatal(err)
114 }
115
116 // Check {Create, BeginUpdate, Close} doesn't work.
117 f = nf()
118 t.Log(f.Name())
119 f.BeginUpdate()
120
121 if err := f.Close(); err == nil {
122 t.Fatal("unexpected success")
123 }
124
125 // Check {Create, BeginUpdate, EndUpdate, Close} works.
126 f = nf()
127 t.Log(f.Name())
128 f.BeginUpdate()
129 if err := f.EndUpdate(); err != nil {
130 f.Close()
131 t.Fatal(err)
132 }
133
134 if err := f.Close(); err != nil {
135 t.Fatal(err)
136 }
137 }
138
139 func TestFilerTruncate(t *testing.T) {
140 testFilerTruncate(t, newFileFiler)
141 testFilerTruncate(t, newOSFileFiler)
142 testFilerTruncate(t, newMemFiler)
143 testFilerTruncate(t, nwBitFiler)
144 testFilerTruncate(t, newRollbackFiler)
145 }
146
147 func testFilerTruncate(t *testing.T, nf newFunc) {
148 f := nf()
149 t.Log(f.Name())
150 defer func() {
151 if err := f.Close(); err != nil {
152 t.Error(err)
153 }
154 }()
155
156 if _, ok := f.(*RollbackFiler); ok {
157 if err := f.BeginUpdate(); err != nil {
158 t.Fatal(err)
159 }
160
161 defer func() {
162 if err := f.EndUpdate(); err != nil {
163 t.Error(err)
164 }
165 }()
166 }
167
168 // Check Truncate works.
169 sz := int64(1e6)
170 if err := f.Truncate(sz); err != nil {
171 t.Error(err)
172 return
173 }
174
175 fsz, err := f.Size()
176 if err != nil {
177 t.Error(err)
178 return
179 }
180
181 if g, e := fsz, sz; g != e {
182 t.Error(g, e)
183 return
184 }
185
186 sz *= 2
187 if err := f.Truncate(sz); err != nil {
188 t.Error(err)
189 return
190 }
191
192 fsz, err = f.Size()
193 if err != nil {
194 t.Error(err)
195 return
196 }
197
198 if g, e := fsz, sz; g != e {
199 t.Error(g, e)
200 return
201 }
202
203 sz = 0
204 if err := f.Truncate(sz); err != nil {
205 t.Error(err)
206 return
207 }
208
209 fsz, err = f.Size()
210 if err != nil {
211 t.Error(err)
212 return
213 }
214
215 if g, e := fsz, sz; g != e {
216 t.Error(g, e)
217 return
218 }
219
220 // Check Truncate(-1) doesn't work.
221 sz = -1
222 if err := f.Truncate(sz); err == nil {
223 t.Error(err)
224 return
225 }
226
227 }
228
229 func TestFilerReadAtWriteAt(t *testing.T) {
230 testFilerReadAtWriteAt(t, newFileFiler)
231 testFilerReadAtWriteAt(t, newOSFileFiler)
232 testFilerReadAtWriteAt(t, newMemFiler)
233 testFilerReadAtWriteAt(t, nwBitFiler)
234 testFilerReadAtWriteAt(t, newRollbackFiler)
235 }
236
237 func testFilerReadAtWriteAt(t *testing.T, nf newFunc) {
238 f := nf()
239 t.Log(f.Name())
240 defer func() {
241 if err := f.Close(); err != nil {
242 t.Error(err)
243 }
244 }()
245
246 if _, ok := f.(*RollbackFiler); ok {
247 if err := f.BeginUpdate(); err != nil {
248 t.Fatal(err)
249 }
250
251 defer func() {
252 if err := f.EndUpdate(); err != nil {
253 t.Error(err)
254 }
255 }()
256 }
257
258 const (
259 N = 1 << 16
260 M = 2e2
261 )
262
263 s := make([]byte, N)
264 e := make([]byte, N)
265 rnd := rand.New(rand.NewSource(42))
266 for i := range e {
267 s[i] = byte(rnd.Intn(256))
268 }
269 n2 := 0
270 for i := 0; i < M; i++ {
271 var from, to int
272 for {
273 from = rnd.Intn(N)
274 to = rnd.Intn(N)
275 if from != to {
276 break
277 }
278 }
279 if from > to {
280 from, to = to, from
281 }
282 for i := range s[from:to] {
283 s[from+i] = byte(rnd.Intn(256))
284 }
285 copy(e[from:to], s[from:to])
286 if to > n2 {
287 n2 = to
288 }
289 n, err := f.WriteAt(s[from:to], int64(from))
290 if err != nil {
291 t.Error(err)
292 return
293 }
294
295 if g, e := n, to-from; g != e {
296 t.Error(g, e)
297 return
298 }
299 }
300
301 fsz, err := f.Size()
302 if err != nil {
303 t.Error(err)
304 return
305 }
306
307 if g, e := fsz, int64(n2); g != e {
308 t.Error(g, e)
309 return
310 }
311
312 b := make([]byte, n2)
313 for i := 0; i <= M; i++ {
314 from := rnd.Intn(n2)
315 to := rnd.Intn(n2)
316 if from > to {
317 from, to = to, from
318 }
319 if i == M {
320 from, to = 0, n2
321 }
322 n, err := f.ReadAt(b[from:to], int64(from))
323 if err != nil && (!fileutil.IsEOF(err) && n != 0) {
324 fsz, err = f.Size()
325 if err != nil {
326 t.Error(err)
327 return
328 }
329
330 t.Error(fsz, from, to, err)
331 return
332 }
333
334 if g, e := n, to-from; g != e {
335 t.Error(g, e)
336 return
337 }
338
339 if g, e := b[from:to], e[from:to]; !bytes.Equal(g, e) {
340 if x, ok := f.(*MemFiler); ok {
341 for i := int64(0); i <= 3; i++ {
342 t.Logf("pg %d\n----\n%s", i, hex.Dump(x.m[i][:]))
343 }
344 }
345 t.Errorf(
346 "i %d from %d to %d len(g) %d len(e) %d\n---- got ----\n%s\n---- exp ----\n%s",
347 i, from, to, len(g), len(e), hex.Dump(g), hex.Dump(e),
348 )
349 return
350 }
351 }
352
353 mf, ok := f.(*MemFiler)
354 if !ok {
355 return
356 }
357
358 buf := &bytes.Buffer{}
359 if _, err := mf.WriteTo(buf); err != nil {
360 t.Error(err)
361 return
362 }
363
364 if g, e := buf.Bytes(), e[:n2]; !bytes.Equal(g, e) {
365 t.Errorf("\nlen %d\n%s\nlen %d\n%s", len(g), hex.Dump(g), len(e), hex.Dump(e))
366 return
367 }
368
369 if err := mf.Truncate(0); err != nil {
370 t.Error(err)
371 return
372 }
373
374 if _, err := mf.ReadFrom(buf); err != nil {
375 t.Error(err)
376 return
377 }
378
379 roundTrip := make([]byte, n2)
380 if n, err := mf.ReadAt(roundTrip, 0); err != nil && n == 0 {
381 t.Error(err)
382 return
383 }
384
385 if g, e := roundTrip, e[:n2]; !bytes.Equal(g, e) {
386 t.Errorf("\nlen %d\n%s\nlen %d\n%s", len(g), hex.Dump(g), len(e), hex.Dump(e))
387 return
388 }
389 }
390
391 func TestInnerFiler(t *testing.T) {
392 testInnerFiler(t, newFileFiler)
393 testInnerFiler(t, newOSFileFiler)
394 testInnerFiler(t, newMemFiler)
395 testInnerFiler(t, nwBitFiler)
396 testInnerFiler(t, newRollbackFiler)
397 }
398
399 func testInnerFiler(t *testing.T, nf newFunc) {
400 const (
401 HDR_SIZE = 42
402 LONG_OFF = 3330
403 )
404 outer := nf()
405 t.Log(outer.Name())
406 inner := NewInnerFiler(outer, HDR_SIZE)
407 defer func() {
408 if err := outer.Close(); err != nil {
409 t.Error(err)
410 }
411 }()
412
413 if _, ok := outer.(*RollbackFiler); ok {
414 if err := outer.BeginUpdate(); err != nil {
415 t.Fatal(err)
416 }
417
418 defer func() {
419 if err := outer.EndUpdate(); err != nil {
420 t.Error(err)
421 }
422 }()
423 }
424
425 b := []byte{2, 5, 11}
426 n, err := inner.WriteAt(b, -1)
427 if err == nil {
428 t.Error("unexpected success")
429 return
430 }
431
432 n, err = inner.ReadAt(make([]byte, 10), -1)
433 if err == nil {
434 t.Error("unexpected success")
435 return
436 }
437
438 n, err = inner.WriteAt(b, 0)
439 if err != nil {
440 t.Error(err)
441 return
442 }
443
444 if g, e := n, len(b); g != e {
445 t.Error(g, e)
446 return
447 }
448
449 osz, err := outer.Size()
450 if err != nil {
451 t.Error(err)
452 return
453 }
454
455 if g, e := osz, int64(HDR_SIZE+3); g != e {
456 t.Error(g, e)
457 return
458 }
459
460 isz, err := inner.Size()
461 if err != nil {
462 t.Error(err)
463 return
464 }
465
466 if g, e := isz, int64(3); g != e {
467 t.Error(g, e)
468 return
469 }
470
471 rbuf := make([]byte, 3)
472 if n, err = outer.ReadAt(rbuf, 0); err != nil && n == 0 {
473 t.Error(err)
474 return
475 }
476
477 if g, e := n, len(rbuf); g != e {
478 t.Error(g, e)
479 return
480 }
481
482 if g, e := rbuf, make([]byte, 3); !bytes.Equal(g, e) {
483 t.Error(g, e)
484 }
485
486 rbuf = make([]byte, 3)
487 if n, err = outer.ReadAt(rbuf, HDR_SIZE); err != nil && n == 0 {
488 t.Error(err)
489 return
490 }
491
492 if g, e := n, len(rbuf); g != e {
493 t.Error(g, e)
494 return
495 }
496
497 if g, e := rbuf, []byte{2, 5, 11}; !bytes.Equal(g, e) {
498 t.Error(g, e)
499 }
500
501 rbuf = make([]byte, 3)
502 if n, err = inner.ReadAt(rbuf, 0); err != nil && n == 0 {
503 t.Error(err)
504 return
505 }
506
507 if g, e := n, len(rbuf); g != e {
508 t.Error(g, e)
509 return
510 }
511
512 if g, e := rbuf, []byte{2, 5, 11}; !bytes.Equal(g, e) {
513 t.Error(g, e)
514 }
515
516 b = []byte{22, 55, 111}
517 if n, err = inner.WriteAt(b, LONG_OFF); err != nil {
518 t.Error(err)
519 return
520 }
521
522 if g, e := n, len(b); g != e {
523 t.Error(g, e)
524 return
525 }
526
527 osz, err = outer.Size()
528 if err != nil {
529 t.Error(err)
530 return
531 }
532
533 if g, e := osz, int64(HDR_SIZE+LONG_OFF+3); g != e {
534 t.Error(g, e)
535 return
536 }
537
538 isz, err = inner.Size()
539 if err != nil {
540 t.Error(err)
541 return
542 }
543
544 if g, e := isz, int64(LONG_OFF+3); g != e {
545 t.Error(g, e)
546 return
547 }
548
549 rbuf = make([]byte, 3)
550 if n, err = outer.ReadAt(rbuf, HDR_SIZE+LONG_OFF); err != nil && n == 0 {
551 t.Error(err)
552 return
553 }
554
555 if g, e := n, len(rbuf); g != e {
556 t.Error(g, e)
557 return
558 }
559
560 if g, e := rbuf, []byte{22, 55, 111}; !bytes.Equal(g, e) {
561 t.Error(g, e)
562 }
563
564 rbuf = make([]byte, 3)
565 if n, err = inner.ReadAt(rbuf, LONG_OFF); err != nil && n == 0 {
566 t.Error(err)
567 return
568 }
569
570 if g, e := n, len(rbuf); g != e {
571 t.Error(g, e)
572 return
573 }
574
575 if g, e := rbuf, []byte{22, 55, 111}; !bytes.Equal(g, e) {
576 t.Error(g, e)
577 return
578 }
579
580 if err = inner.Truncate(1); err != nil {
581 t.Error(err)
582 return
583 }
584
585 isz, err = inner.Size()
586 if err != nil {
587 t.Error(err)
588 return
589 }
590
591 if g, e := isz, int64(1); g != e {
592 t.Error(g, e)
593 return
594 }
595
596 osz, err = outer.Size()
597 if err != nil {
598 t.Error(err)
599 return
600 }
601
602 if g, e := osz, int64(HDR_SIZE+1); g != e {
603 t.Error(g, e)
604 return
605 }
606 }
607
608 func TestFileReadAtHole(t *testing.T) {
609 testFileReadAtHole(t, newFileFiler)
610 testFileReadAtHole(t, newOSFileFiler)
611 testFileReadAtHole(t, newMemFiler)
612 testFileReadAtHole(t, nwBitFiler)
613 testFileReadAtHole(t, newRollbackFiler)
614 }
615
616 func testFileReadAtHole(t *testing.T, nf newFunc) {
617 f := nf()
618 t.Log(f.Name())
619 defer func() {
620 if err := f.Close(); err != nil {
621 t.Error(err)
622 }
623 }()
624
625 if _, ok := f.(*RollbackFiler); ok {
626 if err := f.BeginUpdate(); err != nil {
627 t.Fatal(err)
628 }
629
630 defer func() {
631 if err := f.EndUpdate(); err != nil {
632 t.Error(err)
633 }
634 }()
635 }
636
637 n, err := f.WriteAt([]byte{1}, 40000)
638 if err != nil {
639 t.Error(err)
640 return
641 }
642
643 if n != 1 {
644 t.Error(n)
645 return
646 }
647
648 n, err = f.ReadAt(make([]byte, 1000), 20000)
649 if err != nil {
650 t.Error(err)
651 return
652 }
653
654 if n != 1000 {
655 t.Error(n)
656 return
657 }
658 }
659
660 func BenchmarkMemFilerWrSeq(b *testing.B) {
661 b.StopTimer()
662 buf := make([]byte, filerTestChunkSize)
663 for i := range buf {
664 buf[i] = byte(rand.Int())
665 }
666 f := newMemFiler()
667 runtime.GC()
668 b.StartTimer()
669 var ofs int64
670 for i := 0; i < b.N; i++ {
671 _, err := f.WriteAt(buf, ofs)
672 if err != nil {
673 b.Fatal(err)
674 }
675
676 ofs = (ofs + filerTestChunkSize) % filerTotalSize
677 }
678 }
679
680 func BenchmarkMemFilerRdSeq(b *testing.B) {
681 b.StopTimer()
682 buf := make([]byte, filerTestChunkSize)
683 for i := range buf {
684 buf[i] = byte(rand.Int())
685 }
686 f := newMemFiler()
687 var ofs int64
688 for i := 0; i < b.N; i++ {
689 _, err := f.WriteAt(buf, ofs)
690 if err != nil {
691 b.Fatal(err)
692 }
693
694 ofs = (ofs + filerTestChunkSize) % filerTotalSize
695 }
696 runtime.GC()
697 b.StartTimer()
698 ofs = 0
699 for i := 0; i < b.N; i++ {
700 n, err := f.ReadAt(buf, ofs)
701 if err != nil && n == 0 {
702 b.Fatal(err)
703 }
704
705 ofs = (ofs + filerTestChunkSize) % filerTotalSize
706 }
707 }
708
709 func BenchmarkMemFilerWrRand(b *testing.B) {
710 b.StopTimer()
711 rng := rand.New(rand.NewSource(42))
712 f := newMemFiler()
713 var bytes int64
714
715 var ofs, runs []int
716 for i := 0; i < b.N; i++ {
717 ofs = append(ofs, rng.Intn(1<<31-1))
718 runs = append(runs, rng.Intn(1<<31-1)%(2*pgSize))
719 }
720 data := make([]byte, 2*pgSize)
721 for i := range data {
722 data[i] = byte(rng.Int())
723 }
724
725 runtime.GC()
726 b.StartTimer()
727 for i, v := range ofs {
728 n := runs[i]
729 bytes += int64(n)
730 f.WriteAt(data[:n], int64(v))
731 }
732 b.StopTimer()
733 }
734
735 func BenchmarkMemFilerRdRand(b *testing.B) {
736 b.StopTimer()
737 rng := rand.New(rand.NewSource(42))
738 f := newMemFiler()
739 var bytes int64
740
741 var ofs, runs []int
742 for i := 0; i < b.N; i++ {
743 ofs = append(ofs, rng.Intn(1<<31-1))
744 runs = append(runs, rng.Intn(1<<31-1)%(2*pgSize))
745 }
746 data := make([]byte, 2*pgSize)
747 for i := range data {
748 data[i] = byte(rng.Int())
749 }
750
751 for i, v := range ofs {
752 n := runs[i]
753 bytes += int64(n)
754 f.WriteAt(data[:n], int64(v))
755 }
756
757 runtime.GC()
758 b.StartTimer()
759 for _, v := range ofs {
760 f.ReadAt(data, int64(v))
761 }
762 b.StopTimer()
763 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 // Utilities to encode/decode and collate Go predeclared scalar types (and the
5 // typeless nil and []byte). The encoding format is a variation of the one
6 // used by the "encoding/gob" package.
7
8 package lldb
9
10 import (
11 "bytes"
12 "fmt"
13 "math"
14
15 "github.com/cznic/mathutil"
16 )
17
18 const (
19 gbNull = iota // 0x00
20 gbFalse // 0x01
21 gbTrue // 0x02
22 gbFloat0 // 0x03
23 gbFloat1 // 0x04
24 gbFloat2 // 0x05
25 gbFloat3 // 0x06
26 gbFloat4 // 0x07
27 gbFloat5 // 0x08
28 gbFloat6 // 0x09
29 gbFloat7 // 0x0a
30 gbFloat8 // 0x0b
31 gbComplex0 // 0x0c
32 gbComplex1 // 0x0d
33 gbComplex2 // 0x0e
34 gbComplex3 // 0x0f
35 gbComplex4 // 0x10
36 gbComplex5 // 0x11
37 gbComplex6 // 0x12
38 gbComplex7 // 0x13
39 gbComplex8 // 0x14
40 gbBytes00 // 0x15
41 gbBytes01 // 0x16
42 gbBytes02 // 0x17
43 gbBytes03 // 0x18
44 gbBytes04 // 0x19
45 gbBytes05 // 0x1a
46 gbBytes06 // 0x1b
47 gbBytes07 // 0x1c
48 gbBytes08 // 0x1d
49 gbBytes09 // 0x1e
50 gbBytes10 // 0x1f
51 gbBytes11 // 0x20
52 gbBytes12 // 0x21
53 gbBytes13 // 0x22
54 gbBytes14 // 0x23
55 gbBytes15 // 0x24
56 gbBytes16 // 0x25
57 gbBytes17 // Ox26
58 gbBytes1 // 0x27
59 gbBytes2 // 0x28: Offset by one to allow 64kB sized []byte.
60 gbString00 // 0x29
61 gbString01 // 0x2a
62 gbString02 // 0x2b
63 gbString03 // 0x2c
64 gbString04 // 0x2d
65 gbString05 // 0x2e
66 gbString06 // 0x2f
67 gbString07 // 0x30
68 gbString08 // 0x31
69 gbString09 // 0x32
70 gbString10 // 0x33
71 gbString11 // 0x34
72 gbString12 // 0x35
73 gbString13 // 0x36
74 gbString14 // 0x37
75 gbString15 // 0x38
76 gbString16 // 0x39
77 gbString17 // 0x3a
78 gbString1 // 0x3b
79 gbString2 // 0x3c
80 gbUintP1 // 0x3d
81 gbUintP2 // 0x3e
82 gbUintP3 // 0x3f
83 gbUintP4 // 0x40
84 gbUintP5 // 0x41
85 gbUintP6 // 0x42
86 gbUintP7 // 0x43
87 gbUintP8 // 0x44
88 gbIntM8 // 0x45
89 gbIntM7 // 0x46
90 gbIntM6 // 0x47
91 gbIntM5 // 0x48
92 gbIntM4 // 0x49
93 gbIntM3 // 0x4a
94 gbIntM2 // 0x4b
95 gbIntM1 // 0x4c
96 gbIntP1 // 0x4d
97 gbIntP2 // 0x4e
98 gbIntP3 // 0x4f
99 gbIntP4 // 0x50
100 gbIntP5 // 0x51
101 gbIntP6 // 0x52
102 gbIntP7 // 0x53
103 gbIntP8 // 0x54
104 gbInt0 // 0x55
105
106 gbIntMax = 255 - gbInt0 // 0xff == 170
107 )
108
109 // EncodeScalars encodes a vector of predeclared scalar type values to a
110 // []byte, making it suitable to store it as a "record" in a DB or to use it as
111 // a key of a BTree.
112 func EncodeScalars(scalars ...interface{}) (b []byte, err error) {
113 for _, scalar := range scalars {
114 switch x := scalar.(type) {
115 default:
116 return nil, &ErrINVAL{"EncodeScalars: unsupported type", fmt.Sprintf("%T in `%#v`", x, scalars)}
117
118 case nil:
119 b = append(b, gbNull)
120
121 case bool:
122 switch x {
123 case false:
124 b = append(b, gbFalse)
125 case true:
126 b = append(b, gbTrue)
127 }
128
129 case float32:
130 encFloat(float64(x), &b)
131 case float64:
132 encFloat(x, &b)
133
134 case complex64:
135 encComplex(complex128(x), &b)
136 case complex128:
137 encComplex(x, &b)
138
139 case string:
140 n := len(x)
141 if n <= 17 {
142 b = append(b, byte(gbString00+n))
143 b = append(b, []byte(x)...)
144 break
145 }
146
147 if n > 65535 {
148 return nil, fmt.Errorf("EncodeScalars: cannot encode string of length %d (limit 65536)", n)
149 }
150
151 pref := byte(gbString1)
152 if n > 255 {
153 pref++
154 }
155 b = append(b, pref)
156 encUint0(uint64(n), &b)
157 b = append(b, []byte(x)...)
158
159 case int8:
160 encInt(int64(x), &b)
161 case int16:
162 encInt(int64(x), &b)
163 case int32:
164 encInt(int64(x), &b)
165 case int64:
166 encInt(x, &b)
167 case int:
168 encInt(int64(x), &b)
169
170 case uint8:
171 encUint(uint64(x), &b)
172 case uint16:
173 encUint(uint64(x), &b)
174 case uint32:
175 encUint(uint64(x), &b)
176 case uint64:
177 encUint(x, &b)
178 case uint:
179 encUint(uint64(x), &b)
180 case []byte:
181 n := len(x)
182 if n <= 17 {
183 b = append(b, byte(gbBytes00+n))
184 b = append(b, []byte(x)...)
185 break
186 }
187
188 if n > 655356 {
189 return nil, fmt.Errorf("EncodeScalars: cannot encode []byte of length %d (limit 65536)", n)
190 }
191
192 pref := byte(gbBytes1)
193 if n > 255 {
194 pref++
195 }
196 b = append(b, pref)
197 if n <= 255 {
198 b = append(b, byte(n))
199 } else {
200 n--
201 b = append(b, byte(n>>8), byte(n))
202 }
203 b = append(b, x...)
204 }
205 }
206 return
207 }
208
209 func encComplex(f complex128, b *[]byte) {
210 encFloatPrefix(gbComplex0, real(f), b)
211 encFloatPrefix(gbComplex0, imag(f), b)
212 }
213
214 func encFloatPrefix(prefix byte, f float64, b *[]byte) {
215 u := math.Float64bits(f)
216 var n uint64
217 for i := 0; i < 8; i++ {
218 n <<= 8
219 n |= u & 0xFF
220 u >>= 8
221 }
222 bits := mathutil.BitLenUint64(n)
223 if bits == 0 {
224 *b = append(*b, prefix)
225 return
226 }
227
228 // 0 1 2 3 4 5 6 7 8 9
229 // . 1 1 1 1 1 1 1 1 2
230 encUintPrefix(prefix+1+byte((bits-1)>>3), n, b)
231 }
232
233 func encFloat(f float64, b *[]byte) {
234 encFloatPrefix(gbFloat0, f, b)
235 }
236
237 func encUint0(n uint64, b *[]byte) {
238 switch {
239 case n <= 0xff:
240 *b = append(*b, byte(n))
241 case n <= 0xffff:
242 *b = append(*b, byte(n>>8), byte(n))
243 case n <= 0xffffff:
244 *b = append(*b, byte(n>>16), byte(n>>8), byte(n))
245 case n <= 0xffffffff:
246 *b = append(*b, byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
247 case n <= 0xffffffffff:
248 *b = append(*b, byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
249 case n <= 0xffffffffffff:
250 *b = append(*b, byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
251 case n <= 0xffffffffffffff:
252 *b = append(*b, byte(n>>48), byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
253 case n <= math.MaxUint64:
254 *b = append(*b, byte(n>>56), byte(n>>48), byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
255 }
256 }
257
258 func encUintPrefix(prefix byte, n uint64, b *[]byte) {
259 *b = append(*b, prefix)
260 encUint0(n, b)
261 }
262
263 func encUint(n uint64, b *[]byte) {
264 bits := mathutil.Max(1, mathutil.BitLenUint64(n))
265 encUintPrefix(gbUintP1+byte((bits-1)>>3), n, b)
266 }
267
268 func encInt(n int64, b *[]byte) {
269 switch {
270 case n < -0x100000000000000:
271 *b = append(*b, byte(gbIntM8), byte(n>>56), byte(n>>48), byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
272 case n < -0x1000000000000:
273 *b = append(*b, byte(gbIntM7), byte(n>>48), byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
274 case n < -0x10000000000:
275 *b = append(*b, byte(gbIntM6), byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
276 case n < -0x100000000:
277 *b = append(*b, byte(gbIntM5), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
278 case n < -0x1000000:
279 *b = append(*b, byte(gbIntM4), byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
280 case n < -0x10000:
281 *b = append(*b, byte(gbIntM3), byte(n>>16), byte(n>>8), byte(n))
282 case n < -0x100:
283 *b = append(*b, byte(gbIntM2), byte(n>>8), byte(n))
284 case n < 0:
285 *b = append(*b, byte(gbIntM1), byte(n))
286 case n <= gbIntMax:
287 *b = append(*b, byte(gbInt0+n))
288 case n <= 0xff:
289 *b = append(*b, gbIntP1, byte(n))
290 case n <= 0xffff:
291 *b = append(*b, gbIntP2, byte(n>>8), byte(n))
292 case n <= 0xffffff:
293 *b = append(*b, gbIntP3, byte(n>>16), byte(n>>8), byte(n))
294 case n <= 0xffffffff:
295 *b = append(*b, gbIntP4, byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
296 case n <= 0xffffffffff:
297 *b = append(*b, gbIntP5, byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
298 case n <= 0xffffffffffff:
299 *b = append(*b, gbIntP6, byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
300 case n <= 0xffffffffffffff:
301 *b = append(*b, gbIntP7, byte(n>>48), byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
302 case n <= 0x7fffffffffffffff:
303 *b = append(*b, gbIntP8, byte(n>>56), byte(n>>48), byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
304 }
305 }
306
307 func decodeFloat(b []byte) float64 {
308 var u uint64
309 for i, v := range b {
310 u |= uint64(v) << uint((i+8-len(b))*8)
311 }
312 return math.Float64frombits(u)
313 }
314
315 // DecodeScalars decodes a []byte produced by EncodeScalars.
316 func DecodeScalars(b []byte) (scalars []interface{}, err error) {
317 b0 := b
318 for len(b) != 0 {
319 switch tag := b[0]; tag {
320 //default:
321 //return nil, fmt.Errorf("tag %d(%#x) not supported", b[0], b[0])
322 case gbNull:
323 scalars = append(scalars, nil)
324 b = b[1:]
325 case gbFalse:
326 scalars = append(scalars, false)
327 b = b[1:]
328 case gbTrue:
329 scalars = append(scalars, true)
330 b = b[1:]
331 case gbFloat0:
332 scalars = append(scalars, 0.0)
333 b = b[1:]
334 case gbFloat1, gbFloat2, gbFloat3, gbFloat4, gbFloat5, gbFloat6, gbFloat7, gbFloat8:
335 n := 1 + int(tag) - gbFloat0
336 if len(b) < n-1 {
337 goto corrupted
338 }
339
340 scalars = append(scalars, decodeFloat(b[1:n]))
341 b = b[n:]
342 case gbComplex0, gbComplex1, gbComplex2, gbComplex3, gbComplex4, gbComplex5, gbComplex6, gbComplex7, gbComplex8:
343 n := 1 + int(tag) - gbComplex0
344 if len(b) < n-1 {
345 goto corrupted
346 }
347
348 re := decodeFloat(b[1:n])
349 b = b[n:]
350
351 if len(b) == 0 {
352 goto corrupted
353 }
354
355 tag = b[0]
356 if tag < gbComplex0 || tag > gbComplex8 {
357 goto corrupted
358 }
359
360 n = 1 + int(tag) - gbComplex0
361 if len(b) < n-1 {
362 goto corrupted
363 }
364
365 scalars = append(scalars, complex(re, decodeFloat(b[1:n])))
366 b = b[n:]
367 case gbBytes00, gbBytes01, gbBytes02, gbBytes03, gbBytes04,
368 gbBytes05, gbBytes06, gbBytes07, gbBytes08, gbBytes09,
369 gbBytes10, gbBytes11, gbBytes12, gbBytes13, gbBytes14,
370 gbBytes15, gbBytes16, gbBytes17:
371 n := int(tag - gbBytes00)
372 if len(b) < n+1 {
373 goto corrupted
374 }
375
376 scalars = append(scalars, append([]byte(nil), b[1:n+1]...))
377 b = b[n+1:]
378 case gbBytes1:
379 if len(b) < 2 {
380 goto corrupted
381 }
382
383 n := int(b[1])
384 b = b[2:]
385 if len(b) < n {
386 goto corrupted
387 }
388
389 scalars = append(scalars, append([]byte(nil), b[:n]...))
390 b = b[n:]
391 case gbBytes2:
392 if len(b) < 3 {
393 goto corrupted
394 }
395
396 n := int(b[1])<<8 | int(b[2]) + 1
397 b = b[3:]
398 if len(b) < n {
399 goto corrupted
400 }
401
402 scalars = append(scalars, append([]byte(nil), b[:n]...))
403 b = b[n:]
404 case gbString00, gbString01, gbString02, gbString03, gbString04,
405 gbString05, gbString06, gbString07, gbString08, gbString09,
406 gbString10, gbString11, gbString12, gbString13, gbString14,
407 gbString15, gbString16, gbString17:
408 n := int(tag - gbString00)
409 if len(b) < n+1 {
410 goto corrupted
411 }
412
413 scalars = append(scalars, string(b[1:n+1]))
414 b = b[n+1:]
415 case gbString1:
416 if len(b) < 2 {
417 goto corrupted
418 }
419
420 n := int(b[1])
421 b = b[2:]
422 if len(b) < n {
423 goto corrupted
424 }
425
426 scalars = append(scalars, string(b[:n]))
427 b = b[n:]
428 case gbString2:
429 if len(b) < 3 {
430 goto corrupted
431 }
432
433 n := int(b[1])<<8 | int(b[2])
434 b = b[3:]
435 if len(b) < n {
436 goto corrupted
437 }
438
439 scalars = append(scalars, string(b[:n]))
440 b = b[n:]
441 case gbUintP1, gbUintP2, gbUintP3, gbUintP4, gbUintP5, gbUintP6, gbUintP7, gbUintP8:
442 b = b[1:]
443 n := 1 + int(tag) - gbUintP1
444 if len(b) < n {
445 goto corrupted
446 }
447
448 var u uint64
449 for _, v := range b[:n] {
450 u = u<<8 | uint64(v)
451 }
452 scalars = append(scalars, u)
453 b = b[n:]
454 case gbIntM8, gbIntM7, gbIntM6, gbIntM5, gbIntM4, gbIntM3, gbIntM2, gbIntM1:
455 b = b[1:]
456 n := 8 - (int(tag) - gbIntM8)
457 if len(b) < n {
458 goto corrupted
459 }
460 u := uint64(math.MaxUint64)
461 for _, v := range b[:n] {
462 u = u<<8 | uint64(v)
463 }
464 scalars = append(scalars, int64(u))
465 b = b[n:]
466 case gbIntP1, gbIntP2, gbIntP3, gbIntP4, gbIntP5, gbIntP6, gbIntP7, gbIntP8:
467 b = b[1:]
468 n := 1 + int(tag) - gbIntP1
469 if len(b) < n {
470 goto corrupted
471 }
472
473 i := int64(0)
474 for _, v := range b[:n] {
475 i = i<<8 | int64(v)
476 }
477 scalars = append(scalars, i)
478 b = b[n:]
479 default:
480 scalars = append(scalars, int64(b[0])-gbInt0)
481 b = b[1:]
482 }
483 }
484 return append([]interface{}(nil), scalars...), nil
485
486 corrupted:
487 return nil, &ErrDecodeScalars{append([]byte(nil), b0...), len(b0) - len(b)}
488 }
489
490 func collateComplex(x, y complex128) int {
491 switch rx, ry := real(x), real(y); {
492 case rx < ry:
493 return -1
494 case rx == ry:
495 switch ix, iy := imag(x), imag(y); {
496 case ix < iy:
497 return -1
498 case ix == iy:
499 return 0
500 case ix > iy:
501 return 1
502 }
503 }
504 //case rx > ry:
505 return 1
506 }
507
508 func collateFloat(x, y float64) int {
509 switch {
510 case x < y:
511 return -1
512 case x == y:
513 return 0
514 }
515 //case x > y:
516 return 1
517 }
518
519 func collateInt(x, y int64) int {
520 switch {
521 case x < y:
522 return -1
523 case x == y:
524 return 0
525 }
526 //case x > y:
527 return 1
528 }
529
530 func collateUint(x, y uint64) int {
531 switch {
532 case x < y:
533 return -1
534 case x == y:
535 return 0
536 }
537 //case x > y:
538 return 1
539 }
540
541 func collateIntUint(x int64, y uint64) int {
542 if y > math.MaxInt64 {
543 return -1
544 }
545
546 return collateInt(x, int64(y))
547 }
548
549 func collateUintInt(x uint64, y int64) int {
550 return -collateIntUint(y, x)
551 }
552
553 func collateType(i interface{}) (r interface{}, err error) {
554 switch x := i.(type) {
555 default:
556 return nil, fmt.Errorf("invalid collate type %T", x)
557 case nil:
558 return i, nil
559 case bool:
560 return i, nil
561 case int8:
562 return int64(x), nil
563 case int16:
564 return int64(x), nil
565 case int32:
566 return int64(x), nil
567 case int64:
568 return i, nil
569 case int:
570 return int64(x), nil
571 case uint8:
572 return uint64(x), nil
573 case uint16:
574 return uint64(x), nil
575 case uint32:
576 return uint64(x), nil
577 case uint64:
578 return i, nil
579 case uint:
580 return uint64(x), nil
581 case float32:
582 return float64(x), nil
583 case float64:
584 return i, nil
585 case complex64:
586 return complex128(x), nil
587 case complex128:
588 return i, nil
589 case []byte:
590 return i, nil
591 case string:
592 return i, nil
593 }
594 }
595
596 // Collate collates two arrays of Go predeclared scalar types (and the typeless
597 // nil or []byte). If any other type appears in x or y, Collate will return a
598 // non nil error. String items are collated using strCollate or lexically
599 // byte-wise (as when using Go comparison operators) when strCollate is nil.
600 // []byte items are collated using bytes.Compare.
601 //
602 // Collate returns:
603 //
604 // -1 if x < y
605 // 0 if x == y
606 // +1 if x > y
607 //
608 // The same value as defined above must be returned from strCollate.
609 //
610 // The "outer" ordering is: nil, bool, number, []byte, string. IOW, nil is
611 // "smaller" than anything else except other nil, numbers collate before
612 // []byte, []byte collate before strings, etc.
613 //
614 // Integers and real numbers collate as expected in math. However, complex
615 // numbers are not ordered in Go. Here the ordering is defined: Complex numbers
616 // are in comparison considered first only by their real part. Iff the result
617 // is equality then the imaginary part is used to determine the ordering. In
618 // this "second order" comparing, integers and real numbers are considered as
619 // complex numbers with a zero imaginary part.
620 func Collate(x, y []interface{}, strCollate func(string, string) int) (r int, err error) {
621 nx, ny := len(x), len(y)
622
623 switch {
624 case nx == 0 && ny != 0:
625 return -1, nil
626 case nx == 0 && ny == 0:
627 return 0, nil
628 case nx != 0 && ny == 0:
629 return 1, nil
630 }
631
632 r = 1
633 if nx > ny {
634 x, y, r = y, x, -r
635 }
636
637 var c int
638 for i, xi0 := range x {
639 yi0 := y[i]
640 xi, err := collateType(xi0)
641 if err != nil {
642 return 0, err
643 }
644
645 yi, err := collateType(yi0)
646 if err != nil {
647 return 0, err
648 }
649
650 switch x := xi.(type) {
651 default:
652 panic(fmt.Errorf("internal error: %T", x))
653
654 case nil:
655 switch yi.(type) {
656 case nil:
657 // nop
658 default:
659 return -r, nil
660 }
661
662 case bool:
663 switch y := yi.(type) {
664 case nil:
665 return r, nil
666 case bool:
667 switch {
668 case !x && y:
669 return -r, nil
670 case x == y:
671 // nop
672 case x && !y:
673 return r, nil
674 }
675 default:
676 return -r, nil
677 }
678
679 case int64:
680 switch y := yi.(type) {
681 case nil, bool:
682 return r, nil
683 case int64:
684 c = collateInt(x, y)
685 case uint64:
686 c = collateIntUint(x, y)
687 case float64:
688 c = collateFloat(float64(x), y)
689 case complex128:
690 c = collateComplex(complex(float64(x), 0), y)
691 case []byte:
692 return -r, nil
693 case string:
694 return -r, nil
695 }
696
697 if c != 0 {
698 return c * r, nil
699 }
700
701 case uint64:
702 switch y := yi.(type) {
703 case nil, bool:
704 return r, nil
705 case int64:
706 c = collateUintInt(x, y)
707 case uint64:
708 c = collateUint(x, y)
709 case float64:
710 c = collateFloat(float64(x), y)
711 case complex128:
712 c = collateComplex(complex(float64(x), 0), y)
713 case []byte:
714 return -r, nil
715 case string:
716 return -r, nil
717 }
718
719 if c != 0 {
720 return c * r, nil
721 }
722
723 case float64:
724 switch y := yi.(type) {
725 case nil, bool:
726 return r, nil
727 case int64:
728 c = collateFloat(x, float64(y))
729 case uint64:
730 c = collateFloat(x, float64(y))
731 case float64:
732 c = collateFloat(x, y)
733 case complex128:
734 c = collateComplex(complex(x, 0), y)
735 case []byte:
736 return -r, nil
737 case string:
738 return -r, nil
739 }
740
741 if c != 0 {
742 return c * r, nil
743 }
744
745 case complex128:
746 switch y := yi.(type) {
747 case nil, bool:
748 return r, nil
749 case int64:
750 c = collateComplex(x, complex(float64(y), 0))
751 case uint64:
752 c = collateComplex(x, complex(float64(y), 0))
753 case float64:
754 c = collateComplex(x, complex(y, 0))
755 case complex128:
756 c = collateComplex(x, y)
757 case []byte:
758 return -r, nil
759 case string:
760 return -r, nil
761 }
762
763 if c != 0 {
764 return c * r, nil
765 }
766
767 case []byte:
768 switch y := yi.(type) {
769 case nil, bool, int64, uint64, float64, complex128:
770 return r, nil
771 case []byte:
772 c = bytes.Compare(x, y)
773 case string:
774 return -r, nil
775 }
776
777 if c != 0 {
778 return c * r, nil
779 }
780
781 case string:
782 switch y := yi.(type) {
783 case nil, bool, int64, uint64, float64, complex128:
784 return r, nil
785 case []byte:
786 return r, nil
787 case string:
788 switch {
789 case strCollate != nil:
790 c = strCollate(x, y)
791 case x < y:
792 return -r, nil
793 case x == y:
794 c = 0
795 case x > y:
796 return r, nil
797 }
798 }
799
800 if c != 0 {
801 return c * r, nil
802 }
803 }
804 }
805
806 if nx == ny {
807 return 0, nil
808 }
809
810 return -r, nil
811 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 // Utilities to encode/decode and collate Go predeclared scalar types. The
5 // encoding format reused the one used by the "encoding/gob" package.
6
7 package lldb
8
9 import (
10 "bytes"
11 "math"
12 "testing"
13 )
14
15 const s256 = "" +
16 "0123456789abcdef" +
17 "0123456789abcdef" +
18 "0123456789abcdef" +
19 "0123456789abcdef" +
20 "0123456789abcdef" +
21 "0123456789abcdef" +
22 "0123456789abcdef" +
23 "0123456789abcdef" +
24 "0123456789abcdef" +
25 "0123456789abcdef" +
26 "0123456789abcdef" +
27 "0123456789abcdef" +
28 "0123456789abcdef" +
29 "0123456789abcdef" +
30 "0123456789abcdef" +
31 "0123456789abcdef"
32
33 func TestEncodeDecodeScalars(t *testing.T) {
34 table := []struct{ v, exp interface{} }{
35 {nil, "00"},
36 {false, "01"},
37 {true, "02"},
38 {math.Float64frombits(0), []byte{gbFloat0}},
39 {17., []byte{gbFloat2, 0x31, 0x40}},
40 {math.Float64frombits(0x4031320000000000), []byte{gbFloat3, 0x32, 0x31, 0x40}},
41 {math.Float64frombits(0x4031323300000000), []byte{gbFloat4, 0x33, 0x32, 0x31, 0x40}},
42 {math.Float64frombits(0x4031323334000000), []byte{gbFloat5, 0x34, 0x33, 0x32, 0x31, 0x40}},
43 {math.Float64frombits(0x4031323334350000), []byte{gbFloat6, 0x35, 0x34, 0x33, 0x32, 0x31, 0x40}},
44 {math.Float64frombits(0x4031323334353600), []byte{gbFloat7, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x40}},
45 {math.Float64frombits(0x4031323334353637), []byte{gbFloat8, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x40}},
46 {0 + 0i, []byte{gbComplex0, gbComplex0}},
47 {17 + 17i, []byte{gbComplex2, 0x31, 0x40, gbComplex2, 0x31, 0x40}},
48 {complex(math.Float64frombits(0x4041420000000000), math.Float64frombits(0x4031320000000000)), []byte{gbComplex3, 0x42, 0x41, 0x40, gbComplex3, 0x32, 0x31, 0x40}},
49 {complex(math.Float64frombits(0x4041424300000000), math.Float64frombits(0x4031323300000000)), []byte{gbComplex4, 0x43, 0x42, 0x41, 0x40, gbComplex4, 0x33, 0x32, 0x31, 0x40}},
50 {complex(math.Float64frombits(0x4041424344000000), math.Float64frombits(0x4031323334000000)), []byte{gbComplex5, 0x44, 0x43, 0x42, 0x41, 0x40, gbComplex5, 0x34, 0x33, 0x32, 0x31, 0x40}},
51 {complex(math.Float64frombits(0x4041424344450000), math.Float64frombits(0x4031323334350000)), []byte{gbComplex6, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, gbComplex6, 0x35, 0x34, 0x33, 0x32, 0x31, 0x40}},
52 {complex(math.Float64frombits(0x4041424344454600), math.Float64frombits(0x4031323334353600)), []byte{gbComplex7, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, gbComplex7, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x40}},
53 {complex(math.Float64frombits(0x4041424344454647), math.Float64frombits(0x4031323334353637)), []byte{gbComplex8, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, gbComplex8, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x40}},
54 {[]byte(""), []byte{gbBytes00}},
55 {[]byte("f"), []byte{gbBytes01, 'f'}},
56 {[]byte("fo"), []byte{gbBytes02, 'f', 'o'}},
57 {[]byte("0123456789abcdefx"), []byte{gbBytes17, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'x'}},
58 {[]byte("0123456789abcdefxy"), []byte{gbBytes1, 18, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'x', 'y'}},
59 {[]byte(s256[:255]), append([]byte{gbBytes1, 0xff}, []byte(s256[:255])...)},
60 {[]byte(s256), append([]byte{gbBytes2, 0x00, 0xff}, []byte(s256)...)},
61 {"", []byte{gbString00}},
62 {"f", []byte{gbString01, 'f'}},
63 {"fo", []byte{gbString02, 'f', 'o'}},
64 {"0123456789abcdefx", []byte{gbString17, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'x'}},
65 {"0123456789abcdefxy", []byte{gbString1, 18, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'x', 'y'}},
66 {s256[:255], append([]byte{gbString1, 0xff}, []byte(s256[:255])...)},
67 {s256, append([]byte{gbString2, 0x01, 0x00}, []byte(s256)...)},
68 {uint64(0xff), []byte{gbUintP1, 255}},
69 {uint64(0xffff), []byte{gbUintP2, 255, 255}},
70 {uint64(0xffffff), []byte{gbUintP3, 255, 255, 255}},
71 {uint64(0xffffffff), []byte{gbUintP4, 255, 255, 255, 255}},
72 {uint64(0xffffffffff), []byte{gbUintP5, 255, 255, 255, 255, 255}},
73 {uint64(0xffffffffffff), []byte{gbUintP6, 255, 255, 255, 255, 255, 255}},
74 {uint64(0xffffffffffffff), []byte{gbUintP7, 255, 255, 255, 255, 255, 255, 255}},
75 {uint64(0xffffffffffffffff), []byte{gbUintP8, 255, 255, 255, 255, 255, 255, 255, 255}},
76 {int64(math.MinInt64), []byte{gbIntM8, 128, 0, 0, 0, 0, 0, 0, 0}},
77 {-int64(0x100000000000000), []byte{gbIntM7, 0, 0, 0, 0, 0, 0, 0}},
78 {-int64(0x1000000000000), []byte{gbIntM6, 0, 0, 0, 0, 0, 0}},
79 {-int64(0x10000000000), []byte{gbIntM5, 0, 0, 0, 0, 0}},
80 {-int64(0x100000000), []byte{gbIntM4, 0, 0, 0, 0}},
81 {-int64(0x1000000), []byte{gbIntM3, 0, 0, 0}},
82 {-int64(0x10000), []byte{gbIntM2, 0, 0}},
83 {-int64(0x100), []byte{gbIntM1, 0}},
84 {-int64(0xff), []byte{gbIntM1, 1}},
85 {-int64(1), []byte{gbIntM1, 255}},
86 {int64(gbIntMax + 1), []byte{gbIntP1, gbIntMax + 1}},
87 {int64(0xff), []byte{gbIntP1, 255}},
88 {int64(0xffff), []byte{gbIntP2, 255, 255}},
89 {int64(0xffffff), []byte{gbIntP3, 255, 255, 255}},
90 {int64(0xffffffff), []byte{gbIntP4, 255, 255, 255, 255}},
91 {int64(0xffffffffff), []byte{gbIntP5, 255, 255, 255, 255, 255}},
92 {int64(0xffffffffffff), []byte{gbIntP6, 255, 255, 255, 255, 255, 255}},
93 {int64(0xffffffffffffff), []byte{gbIntP7, 255, 255, 255, 255, 255, 255, 255}},
94 {int64(0x7fffffffffffffff), []byte{gbIntP8, 127, 255, 255, 255, 255, 255, 255, 255}},
95 {int64(0), []byte{0 + gbInt0}},
96 {int64(1), []byte{1 + gbInt0}},
97 {int64(2), []byte{2 + gbInt0}},
98 {int64(gbIntMax - 2), "fd"},
99 {int64(gbIntMax - 1), "fe"},
100 {int64(gbIntMax), "ff"},
101 }
102
103 for i, v := range table {
104 g, err := EncodeScalars(v.v)
105 if err != nil {
106 t.Fatal(i, err)
107 }
108
109 var e []byte
110 switch x := v.exp.(type) {
111 case string:
112 e = s2b(x)
113 case []byte:
114 e = x
115 }
116
117 if !bytes.Equal(g, e) {
118 t.Fatalf("%d %v\n|% 02x|\n|% 02x|", i, v.v, g, e)
119 }
120
121 t.Logf("%#v |% 02x|", v.v, g)
122
123 dec, err := DecodeScalars(g)
124 if err != nil {
125 t.Fatal(err)
126 }
127
128 if g, e := len(dec), 1; g != e {
129 t.Fatalf("%d %d %#v", g, e, dec)
130 }
131
132 if g, ok := dec[0].([]byte); ok {
133 if e := v.v.([]byte); !bytes.Equal(g, e) {
134 t.Fatal(g, e)
135 }
136
137 continue
138 }
139
140 if g, e := dec[0], v.v; g != e {
141 t.Fatal(g, e)
142 }
143 }
144 }
145
146 func strcmp(a, b string) (r int) {
147 if a < b {
148 return -1
149 }
150
151 if a == b {
152 return 0
153 }
154
155 return 1
156 }
157
158 func TestCollateScalars(t *testing.T) {
159 // all cases must return -1
160 table := []struct{ x, y []interface{} }{
161 {[]interface{}{}, []interface{}{1}},
162 {[]interface{}{1}, []interface{}{2}},
163 {[]interface{}{1, 2}, []interface{}{2, 3}},
164
165 {[]interface{}{nil}, []interface{}{nil, true}},
166 {[]interface{}{nil}, []interface{}{false}},
167 {[]interface{}{nil}, []interface{}{nil, 1}},
168 {[]interface{}{nil}, []interface{}{1}},
169 {[]interface{}{nil}, []interface{}{nil, uint(1)}},
170 {[]interface{}{nil}, []interface{}{uint(1)}},
171 {[]interface{}{nil}, []interface{}{nil, 3.14}},
172 {[]interface{}{nil}, []interface{}{3.14}},
173 {[]interface{}{nil}, []interface{}{nil, 3.14 + 1i}},
174 {[]interface{}{nil}, []interface{}{3.14 + 1i}},
175 {[]interface{}{nil}, []interface{}{nil, []byte("foo")}},
176 {[]interface{}{nil}, []interface{}{[]byte("foo")}},
177 {[]interface{}{nil}, []interface{}{nil, "foo"}},
178 {[]interface{}{nil}, []interface{}{"foo"}},
179
180 {[]interface{}{false}, []interface{}{false, false}},
181 {[]interface{}{false}, []interface{}{false, true}},
182 {[]interface{}{false}, []interface{}{true}},
183 {[]interface{}{false}, []interface{}{false, 1}},
184 {[]interface{}{false}, []interface{}{1}},
185 {[]interface{}{false}, []interface{}{false, uint(1)}},
186 {[]interface{}{false}, []interface{}{uint(1)}},
187 {[]interface{}{false}, []interface{}{false, 1.5}},
188 {[]interface{}{false}, []interface{}{1.5}},
189 {[]interface{}{false}, []interface{}{false, 1.5 + 3i}},
190 {[]interface{}{false}, []interface{}{1.5 + 3i}},
191 {[]interface{}{false}, []interface{}{false, []byte("foo")}},
192 {[]interface{}{false}, []interface{}{[]byte("foo")}},
193 {[]interface{}{false}, []interface{}{false, "foo"}},
194 {[]interface{}{false}, []interface{}{"foo"}},
195
196 {[]interface{}{1}, []interface{}{1, 2}},
197 {[]interface{}{1}, []interface{}{1, 1}},
198 {[]interface{}{1}, []interface{}{1, uint(2)}},
199 {[]interface{}{1}, []interface{}{uint(2)}},
200 {[]interface{}{1}, []interface{}{1, 1.1}},
201 {[]interface{}{1}, []interface{}{1.1}},
202 {[]interface{}{1}, []interface{}{1, 1.1 + 2i}},
203 {[]interface{}{1}, []interface{}{1.1 + 2i}},
204 {[]interface{}{1}, []interface{}{1, []byte("foo")}},
205 {[]interface{}{1}, []interface{}{[]byte("foo")}},
206 {[]interface{}{1}, []interface{}{1, "foo"}},
207 {[]interface{}{1}, []interface{}{"foo"}},
208
209 {[]interface{}{uint(1)}, []interface{}{uint(1), uint(1)}},
210 {[]interface{}{uint(1)}, []interface{}{uint(2)}},
211 {[]interface{}{uint(1)}, []interface{}{uint(1), 2.}},
212 {[]interface{}{uint(1)}, []interface{}{2.}},
213 {[]interface{}{uint(1)}, []interface{}{uint(1), 2. + 0i}},
214 {[]interface{}{uint(1)}, []interface{}{2. + 0i}},
215 {[]interface{}{uint(1)}, []interface{}{uint(1), []byte("foo")}},
216 {[]interface{}{uint(1)}, []interface{}{[]byte("foo")}},
217 {[]interface{}{uint(1)}, []interface{}{uint(1), "foo"}},
218 {[]interface{}{uint(1)}, []interface{}{"foo"}},
219
220 {[]interface{}{1.}, []interface{}{1., 1}},
221 {[]interface{}{1.}, []interface{}{2}},
222 {[]interface{}{1.}, []interface{}{1., uint(1)}},
223 {[]interface{}{1.}, []interface{}{uint(2)}},
224 {[]interface{}{1.}, []interface{}{1., 1.}},
225 {[]interface{}{1.}, []interface{}{1.1}},
226 {[]interface{}{1.}, []interface{}{1., []byte("foo")}},
227 {[]interface{}{1.}, []interface{}{[]byte("foo")}},
228 {[]interface{}{1.}, []interface{}{1., "foo"}},
229 {[]interface{}{1.}, []interface{}{"foo"}},
230
231 {[]interface{}{1 + 2i}, []interface{}{1 + 2i, 1}},
232 {[]interface{}{1 + 2i}, []interface{}{2}},
233 {[]interface{}{1 + 2i}, []interface{}{1 + 2i, uint(1)}},
234 {[]interface{}{1 + 2i}, []interface{}{uint(2)}},
235 {[]interface{}{1 + 2i}, []interface{}{1 + 2i, 1.1}},
236 {[]interface{}{1 + 2i}, []interface{}{1.1}},
237 {[]interface{}{1 + 2i}, []interface{}{1 + 2i, []byte("foo")}},
238 {[]interface{}{1 + 2i}, []interface{}{[]byte("foo")}},
239 {[]interface{}{1 + 2i}, []interface{}{1 + 2i, "foo"}},
240 {[]interface{}{1 + 2i}, []interface{}{"foo"}},
241
242 {[]interface{}{[]byte("bar")}, []interface{}{[]byte("bar"), []byte("bar")}},
243 {[]interface{}{[]byte("bar")}, []interface{}{[]byte("foo")}},
244 {[]interface{}{[]byte("bar")}, []interface{}{[]byte("c")}},
245 {[]interface{}{[]byte("bar")}, []interface{}{[]byte("bas")}},
246 {[]interface{}{[]byte("bar")}, []interface{}{[]byte("bara")}},
247
248 {[]interface{}{[]byte("bar")}, []interface{}{"bap"}},
249 {[]interface{}{[]byte("bar")}, []interface{}{"bar"}},
250 {[]interface{}{[]byte("bar")}, []interface{}{"bas"}},
251
252 {[]interface{}{"bar"}, []interface{}{"bar", "bar"}},
253 {[]interface{}{"bar"}, []interface{}{"foo"}},
254 {[]interface{}{"bar"}, []interface{}{"c"}},
255 {[]interface{}{"bar"}, []interface{}{"bas"}},
256 {[]interface{}{"bar"}, []interface{}{"bara"}},
257
258 {[]interface{}{1 + 2i}, []interface{}{1 + 3i}},
259 {[]interface{}{int64(math.MaxInt64)}, []interface{}{uint64(math.MaxInt64 + 1)}},
260 {[]interface{}{int8(1)}, []interface{}{int16(2)}},
261 {[]interface{}{int32(1)}, []interface{}{uint8(2)}},
262 {[]interface{}{uint16(1)}, []interface{}{uint32(2)}},
263 {[]interface{}{float32(1)}, []interface{}{complex(float32(2), 0)}},
264
265 // resolved bugs
266 {[]interface{}{"Customer"}, []interface{}{"Date"}},
267 {[]interface{}{"Customer"}, []interface{}{"Items", 1, "Quantity"}},
268 }
269
270 more := []interface{}{42, nil, 1, uint(2), 3.0, 4 + 5i, "..."}
271
272 collate := func(x, y []interface{}, strCollate func(string, string) int) (r int) {
273 var err error
274 r, err = Collate(x, y, strCollate)
275 if err != nil {
276 t.Fatal(err)
277 }
278
279 return
280 }
281
282 for _, scf := range []func(string, string) int{nil, strcmp} {
283 for _, prefix := range more {
284 for i, test := range table {
285 var x, y []interface{}
286 if prefix != 42 {
287 x = append(x, prefix)
288 y = append(y, prefix)
289 }
290 x = append(x, test.x...)
291 y = append(y, test.y...)
292
293 // cmp(x, y) == -1
294 if g, e := collate(x, y, scf), -1; g != e {
295 t.Fatal(i, g, e, x, y)
296 }
297
298 // cmp(y, x) == 1
299 if g, e := collate(y, x, scf), 1; g != e {
300 t.Fatal(i, g, e, y, x)
301 }
302
303 src := x
304 for ix := len(src) - 1; ix > 0; ix-- {
305 if g, e := collate(src[:ix], src[:ix], scf), 0; g != e {
306 t.Fatal(ix, g, e)
307 }
308
309 if g, e := collate(src[:ix], src, scf), -1; g != e {
310 t.Fatal(ix, g, e)
311 }
312
313 }
314
315 src = y
316 for ix := len(src) - 1; ix > 0; ix-- {
317 if g, e := collate(src[:ix], src[:ix], scf), 0; g != e {
318 t.Fatal(ix, g, e)
319 }
320
321 if g, e := collate(src[:ix], src, scf), -1; g != e {
322 t.Fatal(ix, g, e)
323 }
324
325 }
326 }
327 }
328 }
329 }
330
331 func TestEncodingBug(t *testing.T) {
332 bits := uint64(0)
333 for i := 0; i <= 64; i++ {
334 encoded, err := EncodeScalars(math.Float64frombits(bits))
335 if err != nil {
336 t.Fatal(err)
337 }
338
339 t.Logf("bits %016x, enc |% x|", bits, encoded)
340 decoded, err := DecodeScalars(encoded)
341 if err != nil {
342 t.Fatal(err)
343 }
344
345 if g, e := len(decoded), 1; g != e {
346 t.Fatal(g, e)
347 }
348
349 f, ok := decoded[0].(float64)
350 if !ok {
351 t.Fatal(err)
352 }
353
354 if g, e := math.Float64bits(f), bits; g != e {
355 t.Fatal(err)
356 }
357
358 t.Log(f)
359
360 bits >>= 1
361 bits |= 1 << 63
362 }
363 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 // Package lldb (WIP) implements a low level database engine. The database
5 // model used could be considered a specific implementation of some small(est)
6 // intersection of models listed in [1]. As a settled term is lacking, it'll be
7 // called here a 'Virtual memory model' (VMM).
8 //
9 // Experimental release notes
10 //
11 // This is an experimental release. Don't open a DB from two applications or
12 // two instances of an application - it will get corrupted (no file locking is
13 // implemented and this task is delegated to lldb's clients).
14 //
15 // WARNING: THE LLDB API IS SUBJECT TO CHANGE.
16 //
17 // Filers
18 //
19 // A Filer is an abstraction of storage. A Filer may be a part of some process'
20 // virtual address space, an OS file, a networked, remote file etc. Persistence
21 // of the storage is optional, opaque to VMM and it is specific to a concrete
22 // Filer implementation.
23 //
24 // Space management
25 //
26 // Mechanism to allocate, reallocate (resize), deallocate (and later reclaim
27 // the unused) contiguous parts of a Filer, called blocks. Blocks are
28 // identified and referred to by a handle, an int64.
29 //
30 // BTrees
31 //
32 // In addition to the VMM like services, lldb provides volatile and
33 // non-volatile BTrees. Keys and values of a BTree are limited in size to 64kB
34 // each (a bit more actually). Support for larger keys/values, if desired, can
35 // be built atop a BTree to certain limits.
36 //
37 // Handles vs pointers
38 //
39 // A handle is the abstracted storage counterpart of a memory address. There
40 // is one fundamental difference, though. Resizing a block never results in a
41 // change to the handle which refers to the resized block, so a handle is more
42 // akin to an unique numeric id/key. Yet it shares one property of pointers -
43 // handles can be associated again with blocks after the original handle block
44 // was deallocated. In other words, a handle uniqueness domain is the state of
45 // the database and is not something comparable to e.g. an ever growing
46 // numbering sequence.
47 //
48 // Also, as with memory pointers, dangling handles can be created and blocks
49 // overwritten when such handles are used. Using a zero handle to refer to a
50 // block will not panic; however, the resulting error is effectively the same
51 // exceptional situation as dereferencing a nil pointer.
52 //
53 // Blocks
54 //
55 // Allocated/used blocks, are limited in size to only a little bit more than
56 // 64kB. Bigger semantic entities/structures must be built in lldb's client
57 // code. The content of a block has no semantics attached, it's only a fully
58 // opaque `[]byte`.
59 //
60 // Scalars
61 //
62 // Use of "scalars" applies to EncodeScalars, DecodeScalars and Collate. Those
63 // first two "to bytes" and "from bytes" functions are suggested for handling
64 // multi-valued Allocator content items and/or keys/values of BTrees (using
65 // Collate for keys). Types called "scalar" are:
66 //
67 // nil (the typeless one)
68 // bool
69 // all integral types: [u]int8, [u]int16, [u]int32, [u]int, [u]int64
70 // all floating point types: float32, float64
71 // all complex types: complex64, complex128
72 // []byte (64kB max)
73 // string (64kb max)
74 //
75 // Specific implementations
76 //
77 // Included are concrete implementations of some of the VMM interfaces included
78 // to ease serving simple client code or for testing and possibly as an
79 // example. More details in the documentation of such implementations.
80 //
81 // [1]: http://en.wikipedia.org/wiki/Database_model
82 package lldb
83
84 const (
85 fltSz = 0x70 // size of the FLT
86 maxShort = 251
87 maxRq = 65787
88 maxFLTRq = 4112
89 maxHandle = 1<<56 - 1
90 atomLen = 16
91 tagUsedLong = 0xfc
92 tagUsedRelocated = 0xfd
93 tagFreeShort = 0xfe
94 tagFreeLong = 0xff
95 tagNotCompressed = 0
96 tagCompressed = 1
97 )
98
99 // Content size n -> blocksize in atoms.
100 func n2atoms(n int) int {
101 if n > maxShort {
102 n += 2
103 }
104 return (n+1)/16 + 1
105 }
106
107 // Content size n -> number of padding zeros.
108 func n2padding(n int) int {
109 if n > maxShort {
110 n += 2
111 }
112 return 15 - (n+1)&15
113 }
114
115 // Handle <-> offset
116 func h2off(h int64) int64 { return (h + 6) * 16 }
117 func off2h(off int64) int64 { return off/16 - 6 }
118
119 // Get a 7B int64 from b
120 func b2h(b []byte) (h int64) {
121 for _, v := range b[:7] {
122 h = h<<8 | int64(v)
123 }
124 return
125 }
126
127 // Put a 7B int64 into b
128 func h2b(b []byte, h int64) []byte {
129 for i := range b[:7] {
130 b[i], h = byte(h>>48), h<<8
131 }
132 return b
133 }
134
135 // Content length N (must be in [252, 65787]) to long used block M field.
136 func n2m(n int) (m int) {
137 return n % 0x10000
138 }
139
140 // Long used block M (must be in [0, 65535]) field to content length N.
141 func m2n(m int) (n int) {
142 if m <= maxShort {
143 m += 0x10000
144 }
145 return m
146 }
147
148 func bpack(a []byte) []byte {
149 if cap(a) > len(a) {
150 return append([]byte(nil), a...)
151 }
152
153 return a
154 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 package lldb
5
6 import (
7 "bytes"
8 "encoding/hex"
9 "strings"
10 "testing"
11 )
12
13 func TestN2Atoms(t *testing.T) {
14 tab := []struct{ n, a int }{
15 {0, 1},
16 {1, 1},
17 {2, 1},
18 {3, 1},
19 {4, 1},
20 {5, 1},
21 {6, 1},
22 {7, 1},
23 {8, 1},
24 {9, 1},
25 {10, 1},
26 {11, 1},
27 {12, 1},
28 {13, 1},
29 {14, 1},
30
31 {15, 2},
32 {16, 2},
33 {17, 2},
34 {18, 2},
35 {19, 2},
36 {20, 2},
37 {21, 2},
38 {22, 2},
39 {23, 2},
40 {24, 2},
41 {25, 2},
42 {26, 2},
43 {27, 2},
44 {28, 2},
45 {29, 2},
46 {30, 2},
47
48 {31, 3},
49
50 {252, 16},
51 {253, 17},
52 {254, 17},
53 {255, 17},
54 {256, 17},
55 {257, 17},
56 {258, 17},
57 {259, 17},
58 {260, 17},
59 {261, 17},
60 {262, 17},
61 {263, 17},
62 {264, 17},
63 {265, 17},
64 {266, 17},
65 {267, 17},
66 {268, 17},
67 {269, 18},
68 {65532, 4096},
69 {65533, 4097},
70 {65787, 4112},
71 }
72
73 for i, test := range tab {
74 if g, e := n2atoms(test.n), test.a; g != e {
75 t.Errorf("(%d) %d %d %d", i, test.n, g, e)
76 }
77 }
78 }
79
80 func TestN2Padding(t *testing.T) {
81 tab := []struct{ n, p int }{
82 {0, 14},
83 {1, 13},
84 {2, 12},
85 {3, 11},
86 {4, 10},
87 {5, 9},
88 {6, 8},
89 {7, 7},
90 {8, 6},
91 {9, 5},
92 {10, 4},
93 {11, 3},
94 {12, 2},
95 {13, 1},
96 {14, 0},
97
98 {15, 15},
99 {16, 14},
100 {17, 13},
101 {18, 12},
102 {19, 11},
103 {20, 10},
104 {21, 9},
105 {22, 8},
106 {23, 7},
107 {24, 6},
108 {25, 5},
109 {26, 4},
110 {27, 3},
111 {28, 2},
112 {29, 1},
113 {30, 0},
114
115 {31, 15},
116
117 {252, 0},
118 {253, 15},
119 {254, 14},
120 {255, 13},
121 {256, 12},
122 {257, 11},
123 {258, 10},
124 {259, 9},
125 {260, 8},
126 {261, 7},
127 {262, 6},
128 {263, 5},
129 {264, 4},
130 {265, 3},
131 {266, 2},
132 {267, 1},
133 {268, 0},
134 {269, 15},
135 }
136
137 for i, test := range tab {
138 if g, e := n2padding(test.n), test.p; g != e {
139 t.Errorf("(%d) %d %d %d", i, test.n, g, e)
140 }
141 }
142 }
143
144 func TestH2Off(t *testing.T) {
145 tab := []struct{ h, off int64 }{
146 {-1, fltSz - 32},
147 {0, fltSz - 16},
148 {1, fltSz + 0},
149 {2, fltSz + 16},
150 {3, fltSz + 32},
151 }
152
153 for i, test := range tab {
154 if g, e := h2off(test.h), test.off; g != e {
155 t.Error("h2off", i, g, e)
156 }
157 if g, e := off2h(test.off), test.h; g != e {
158 t.Error("off2h", i, g, e)
159 }
160 }
161 }
162
163 func TestB2H(t *testing.T) {
164 tab := []struct {
165 b []byte
166 h int64
167 }{
168 {[]byte{0, 0, 0, 0, 0, 0, 0}, 0},
169 {[]byte{0, 0, 0, 0, 0, 0, 1}, 1},
170 {[]byte{0, 0, 0, 0, 0, 0, 1, 2}, 1},
171 {[]byte{0, 0, 0, 0, 0, 0x32, 0x10}, 0x3210},
172 {[]byte{0, 0, 0, 0, 0x54, 0x32, 0x10}, 0x543210},
173 {[]byte{0, 0, 0, 0x76, 0x54, 0x32, 0x10}, 0x76543210},
174 {[]byte{0, 0, 0x98, 0x76, 0x54, 0x32, 0x10}, 0x9876543210},
175 {[]byte{0, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, 0xba9876543210},
176 {[]byte{0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}, 0xdcba9876543210},
177 }
178
179 for i, test := range tab {
180 if g, e := b2h(test.b), test.h; g != e {
181 t.Errorf("b2h: %d %#8x %#8x", i, g, e)
182 }
183 var g [7]byte
184 h2b(g[:], test.h)
185 if e := test.b; !bytes.Equal(g[:], e[:7]) {
186 t.Errorf("b2h: %d g: % 0x e: % 0x", i, g, e)
187 }
188 }
189 }
190
191 func s2b(s string) []byte {
192 if s == "" {
193 return nil
194 }
195
196 s = strings.Replace(s, " ", "", -1)
197 if n := len(s) & 1; n != 0 {
198 panic(n)
199 }
200 b, err := hex.DecodeString(s)
201 if err != nil {
202 panic(err)
203 }
204 return b
205 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 // A memory-only implementation of Filer.
5
6 /*
7
8 pgBits: 8
9 BenchmarkMemFilerWrSeq 100000 19430 ns/op 1646.93 MB/s
10 BenchmarkMemFilerRdSeq 100000 17390 ns/op 1840.13 MB/s
11 BenchmarkMemFilerWrRand 1000000 1903 ns/op 133.94 MB/s
12 BenchmarkMemFilerRdRand 1000000 1153 ns/op 221.16 MB/s
13
14 pgBits: 9
15 BenchmarkMemFilerWrSeq 100000 16195 ns/op 1975.80 MB/s
16 BenchmarkMemFilerRdSeq 200000 13011 ns/op 2459.39 MB/s
17 BenchmarkMemFilerWrRand 1000000 2248 ns/op 227.28 MB/s
18 BenchmarkMemFilerRdRand 1000000 1177 ns/op 433.94 MB/s
19
20 pgBits: 10
21 BenchmarkMemFilerWrSeq 100000 16169 ns/op 1979.04 MB/s
22 BenchmarkMemFilerRdSeq 200000 12673 ns/op 2524.91 MB/s
23 BenchmarkMemFilerWrRand 1000000 5550 ns/op 184.30 MB/s
24 BenchmarkMemFilerRdRand 1000000 1699 ns/op 601.79 MB/s
25
26 pgBits: 11
27 BenchmarkMemFilerWrSeq 100000 13449 ns/op 2379.31 MB/s
28 BenchmarkMemFilerRdSeq 200000 12058 ns/op 2653.80 MB/s
29 BenchmarkMemFilerWrRand 500000 4335 ns/op 471.47 MB/s
30 BenchmarkMemFilerRdRand 1000000 2843 ns/op 719.47 MB/s
31
32 pgBits: 12
33 BenchmarkMemFilerWrSeq 200000 11976 ns/op 2672.00 MB/s
34 BenchmarkMemFilerRdSeq 200000 12255 ns/op 2611.06 MB/s
35 BenchmarkMemFilerWrRand 200000 8058 ns/op 507.14 MB/s
36 BenchmarkMemFilerRdRand 500000 4365 ns/op 936.15 MB/s
37
38 pgBits: 13
39 BenchmarkMemFilerWrSeq 200000 10852 ns/op 2948.69 MB/s
40 BenchmarkMemFilerRdSeq 200000 11561 ns/op 2767.77 MB/s
41 BenchmarkMemFilerWrRand 200000 9748 ns/op 840.15 MB/s
42 BenchmarkMemFilerRdRand 500000 7236 ns/op 1131.59 MB/s
43
44 pgBits: 14
45 BenchmarkMemFilerWrSeq 200000 10328 ns/op 3098.12 MB/s
46 BenchmarkMemFilerRdSeq 200000 11292 ns/op 2833.66 MB/s
47 BenchmarkMemFilerWrRand 100000 16768 ns/op 978.75 MB/s
48 BenchmarkMemFilerRdRand 200000 13033 ns/op 1258.43 MB/s
49
50 pgBits: 15
51 BenchmarkMemFilerWrSeq 200000 10309 ns/op 3103.93 MB/s
52 BenchmarkMemFilerRdSeq 200000 11126 ns/op 2876.12 MB/s
53 BenchmarkMemFilerWrRand 50000 31985 ns/op 1021.74 MB/s
54 BenchmarkMemFilerRdRand 100000 25217 ns/op 1297.65 MB/s
55
56 pgBits: 16
57 BenchmarkMemFilerWrSeq 200000 10324 ns/op 3099.45 MB/s
58 BenchmarkMemFilerRdSeq 200000 11201 ns/op 2856.80 MB/s
59 BenchmarkMemFilerWrRand 20000 55226 ns/op 1184.76 MB/s
60 BenchmarkMemFilerRdRand 50000 48316 ns/op 1355.16 MB/s
61
62 pgBits: 17
63 BenchmarkMemFilerWrSeq 200000 10377 ns/op 3083.53 MB/s
64 BenchmarkMemFilerRdSeq 200000 11018 ns/op 2904.18 MB/s
65 BenchmarkMemFilerWrRand 10000 143425 ns/op 913.12 MB/s
66 BenchmarkMemFilerRdRand 20000 95267 ns/op 1376.99 MB/s
67
68 pgBits: 18
69 BenchmarkMemFilerWrSeq 200000 10312 ns/op 3102.96 MB/s
70 BenchmarkMemFilerRdSeq 200000 11069 ns/op 2890.84 MB/s
71 BenchmarkMemFilerWrRand 5000 280910 ns/op 934.14 MB/s
72 BenchmarkMemFilerRdRand 10000 188500 ns/op 1388.17 MB/s
73
74 */
75
76 package lldb
77
78 import (
79 "bytes"
80 "fmt"
81 "io"
82
83 "github.com/cznic/fileutil"
84 "github.com/cznic/mathutil"
85 )
86
87 const (
88 pgBits = 16
89 pgSize = 1 << pgBits
90 pgMask = pgSize - 1
91 )
92
93 var _ Filer = &MemFiler{} // Ensure MemFiler is a Filer.
94
95 type memFilerMap map[int64]*[pgSize]byte
96
97 // MemFiler is a memory backed Filer. It implements BeginUpdate, EndUpdate and
98 // Rollback as no-ops. MemFiler is not automatically persistent, but it has
99 // ReadFrom and WriteTo methods.
100 type MemFiler struct {
101 m memFilerMap
102 nest int
103 size int64
104 }
105
106 // NewMemFiler returns a new MemFiler.
107 func NewMemFiler() *MemFiler {
108 return &MemFiler{m: memFilerMap{}}
109 }
110
111 // BeginUpdate implements Filer.
112 func (f *MemFiler) BeginUpdate() error {
113 f.nest++
114 return nil
115 }
116
117 // Close implements Filer.
118 func (f *MemFiler) Close() (err error) {
119 if f.nest != 0 {
120 return &ErrPERM{(f.Name() + ":Close")}
121 }
122
123 return
124 }
125
126 // EndUpdate implements Filer.
127 func (f *MemFiler) EndUpdate() (err error) {
128 if f.nest == 0 {
129 return &ErrPERM{(f.Name() + ": EndUpdate")}
130 }
131
132 f.nest--
133 return
134 }
135
136 // Name implements Filer.
137 func (f *MemFiler) Name() string {
138 return fmt.Sprintf("%p.memfiler", f)
139 }
140
141 // PunchHole implements Filer.
142 func (f *MemFiler) PunchHole(off, size int64) (err error) {
143 if off < 0 {
144 return &ErrINVAL{f.Name() + ": PunchHole off", off}
145 }
146
147 if size < 0 || off+size > f.size {
148 return &ErrINVAL{f.Name() + ": PunchHole size", size}
149 }
150
151 first := off >> pgBits
152 if off&pgMask != 0 {
153 first++
154 }
155 off += size - 1
156 last := off >> pgBits
157 if off&pgMask != 0 {
158 last--
159 }
160 if limit := f.size >> pgBits; last > limit {
161 last = limit
162 }
163 for pg := first; pg <= last; pg++ {
164 delete(f.m, pg)
165 }
166 return
167 }
168
169 var zeroPage [pgSize]byte
170
171 // ReadAt implements Filer.
172 func (f *MemFiler) ReadAt(b []byte, off int64) (n int, err error) {
173 avail := f.size - off
174 pgI := off >> pgBits
175 pgO := int(off & pgMask)
176 rem := len(b)
177 if int64(rem) >= avail {
178 rem = int(avail)
179 err = io.EOF
180 }
181 for rem != 0 && avail > 0 {
182 pg := f.m[pgI]
183 if pg == nil {
184 pg = &zeroPage
185 }
186 nc := copy(b[:mathutil.Min(rem, pgSize)], pg[pgO:])
187 pgI++
188 pgO = 0
189 rem -= nc
190 n += nc
191 b = b[nc:]
192 }
193 return
194 }
195
196 // ReadFrom is a helper to populate MemFiler's content from r. 'n' reports the
197 // number of bytes read from 'r'.
198 func (f *MemFiler) ReadFrom(r io.Reader) (n int64, err error) {
199 if err = f.Truncate(0); err != nil {
200 return
201 }
202
203 var (
204 b [pgSize]byte
205 rn int
206 off int64
207 )
208
209 var rerr error
210 for rerr == nil {
211 if rn, rerr = r.Read(b[:]); rn != 0 {
212 f.WriteAt(b[:rn], off)
213 off += int64(rn)
214 n += int64(rn)
215 }
216 }
217 if !fileutil.IsEOF(rerr) {
218 err = rerr
219 }
220 return
221 }
222
223 // Rollback implements Filer.
224 func (f *MemFiler) Rollback() (err error) { return }
225
226 // Size implements Filer.
227 func (f *MemFiler) Size() (int64, error) {
228 return f.size, nil
229 }
230
231 // Sync implements Filer.
232 func (f *MemFiler) Sync() error {
233 return nil
234 }
235
236 // Truncate implements Filer.
237 func (f *MemFiler) Truncate(size int64) (err error) {
238 switch {
239 case size < 0:
240 return &ErrINVAL{"Truncate size", size}
241 case size == 0:
242 f.m = memFilerMap{}
243 f.size = 0
244 return
245 }
246
247 first := size >> pgBits
248 if size&pgMask != 0 {
249 first++
250 }
251 last := f.size >> pgBits
252 if f.size&pgMask != 0 {
253 last++
254 }
255 for ; first < last; first++ {
256 delete(f.m, first)
257 }
258
259 f.size = size
260 return
261 }
262
263 // WriteAt implements Filer.
264 func (f *MemFiler) WriteAt(b []byte, off int64) (n int, err error) {
265 pgI := off >> pgBits
266 pgO := int(off & pgMask)
267 n = len(b)
268 rem := n
269 var nc int
270 for rem != 0 {
271 if pgO == 0 && rem >= pgSize && bytes.Equal(b[:pgSize], zeroPage[:]) {
272 delete(f.m, pgI)
273 nc = pgSize
274 } else {
275 pg := f.m[pgI]
276 if pg == nil {
277 pg = new([pgSize]byte)
278 f.m[pgI] = pg
279 }
280 nc = copy((*pg)[pgO:], b)
281 }
282 pgI++
283 pgO = 0
284 rem -= nc
285 b = b[nc:]
286 }
287 f.size = mathutil.MaxInt64(f.size, off+int64(n))
288 return
289 }
290
291 // WriteTo is a helper to copy/persist MemFiler's content to w. If w is also
292 // an io.WriterAt then WriteTo may attempt to _not_ write any big, for some
293 // value of big, runs of zeros, i.e. it will attempt to punch holes, where
294 // possible, in `w` if that happens to be a freshly created or to zero length
295 // truncated OS file. 'n' reports the number of bytes written to 'w'.
296 func (f *MemFiler) WriteTo(w io.Writer) (n int64, err error) {
297 var (
298 b [pgSize]byte
299 wn, rn int
300 off int64
301 rerr error
302 )
303
304 if wa, ok := w.(io.WriterAt); ok {
305 lastPgI := f.size >> pgBits
306 for pgI := int64(0); pgI <= lastPgI; pgI++ {
307 sz := pgSize
308 if pgI == lastPgI {
309 sz = int(f.size & pgMask)
310 }
311 pg := f.m[pgI]
312 if pg != nil {
313 wn, err = wa.WriteAt(pg[:sz], off)
314 if err != nil {
315 return
316 }
317
318 n += int64(wn)
319 off += int64(sz)
320 if wn != sz {
321 return n, io.ErrShortWrite
322 }
323 }
324 }
325 return
326 }
327
328 var werr error
329 for rerr == nil {
330 if rn, rerr = f.ReadAt(b[:], off); rn != 0 {
331 off += int64(rn)
332 if wn, werr = w.Write(b[:rn]); werr != nil {
333 return n, werr
334 }
335
336 n += int64(wn)
337 }
338 }
339 if !fileutil.IsEOF(rerr) {
340 err = rerr
341 }
342 return
343 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 package lldb
5
6 import (
7 "bytes"
8 "math/rand"
9 "testing"
10 )
11
12 // Test automatic page releasing (hole punching) of zero pages
13 func TestMemFilerWriteAt(t *testing.T) {
14 f := NewMemFiler()
15
16 // Add page index 0
17 if _, err := f.WriteAt([]byte{1}, 0); err != nil {
18 t.Fatal(err)
19 }
20
21 if g, e := len(f.m), 1; g != e {
22 t.Fatal(g, e)
23 }
24
25 // Add page index 1
26 if _, err := f.WriteAt([]byte{2}, pgSize); err != nil {
27 t.Fatal(err)
28 }
29
30 if g, e := len(f.m), 2; g != e {
31 t.Fatal(g, e)
32 }
33
34 // Add page index 2
35 if _, err := f.WriteAt([]byte{3}, 2*pgSize); err != nil {
36 t.Fatal(err)
37 }
38
39 if g, e := len(f.m), 3; g != e {
40 t.Fatal(g, e)
41 }
42
43 // Remove page index 1
44 if _, err := f.WriteAt(make([]byte, 2*pgSize), pgSize/2); err != nil {
45 t.Fatal(err)
46 }
47
48 if g, e := len(f.m), 2; g != e {
49 t.Logf("%#v", f.m)
50 t.Fatal(g, e)
51 }
52
53 if err := f.Truncate(1); err != nil {
54 t.Fatal(err)
55 }
56
57 if g, e := len(f.m), 1; g != e {
58 t.Logf("%#v", f.m)
59 t.Fatal(g, e)
60 }
61
62 if err := f.Truncate(0); err != nil {
63 t.Fatal(err)
64 }
65
66 if g, e := len(f.m), 0; g != e {
67 t.Logf("%#v", f.m)
68 t.Fatal(g, e)
69 }
70 }
71
72 func TestMemFilerWriteTo(t *testing.T) {
73 const max = 1e5
74 var b [max]byte
75 rng := rand.New(rand.NewSource(42))
76 for sz := 0; sz < 1e5; sz += 2053 {
77 for i := range b[:sz] {
78 b[i] = byte(rng.Int())
79 }
80 f := NewMemFiler()
81 if n, err := f.WriteAt(b[:sz], 0); n != sz || err != nil {
82 t.Fatal(n, err)
83 }
84
85 var buf bytes.Buffer
86 if n, err := f.WriteTo(&buf); n != int64(sz) || err != nil {
87 t.Fatal(n, err)
88 }
89
90 if !bytes.Equal(b[:sz], buf.Bytes()) {
91 t.Fatal("content differs")
92 }
93 }
94 }
95
96 func TestMemFilerReadFromWriteTo(t *testing.T) {
97 const (
98 sz = 1e2 * pgSize
99 hole = 1e1 * pgSize
100 )
101 rng := rand.New(rand.NewSource(42))
102 data := make([]byte, sz)
103 for i := range data {
104 data[i] = byte(rng.Int())
105 }
106 f := NewMemFiler()
107 buf := bytes.NewBuffer(data)
108 if n, err := f.ReadFrom(buf); n != int64(len(data)) || err != nil {
109 t.Fatal(n, err)
110 }
111
112 buf = bytes.NewBuffer(nil)
113 if n, err := f.WriteTo(buf); n != int64(len(data)) || err != nil {
114 t.Fatal(n, err)
115 }
116
117 rd := buf.Bytes()
118 if !bytes.Equal(data, rd) {
119 t.Fatal("corrupted data")
120 }
121
122 n0 := len(f.m)
123 data = make([]byte, hole)
124 f.WriteAt(data, sz/2)
125 n := len(f.m)
126 t.Log(n0, n)
127 d := n0 - n
128 if d*pgSize < hole-2 || d*pgSize > hole {
129 t.Fatal(n0, n, d)
130 }
131 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 package lldb
5
6 import (
7 "io"
8 "os"
9
10 "github.com/cznic/mathutil"
11 )
12
13 var _ Filer = (*OSFiler)(nil)
14
15 // OSFile is an os.File like minimal set of methods allowing to construct a
16 // Filer.
17 type OSFile interface {
18 Name() string
19 Stat() (fi os.FileInfo, err error)
20 Sync() (err error)
21 Truncate(size int64) (err error)
22 io.Closer
23 io.Reader
24 io.ReaderAt
25 io.Seeker
26 io.Writer
27 io.WriterAt
28 }
29
30 // OSFiler is like a SimpleFileFiler but based on an OSFile.
31 type OSFiler struct {
32 f OSFile
33 nest int
34 size int64 // not set if < 0
35 }
36
37 // NewOSFiler returns a Filer from an OSFile. This Filer is like the
38 // SimpleFileFiler, it does not implement the transaction related methods.
39 func NewOSFiler(f OSFile) (r *OSFiler) {
40 return &OSFiler{
41 f: f,
42 size: -1,
43 }
44 }
45
46 // BeginUpdate implements Filer.
47 func (f *OSFiler) BeginUpdate() (err error) {
48 f.nest++
49 return nil
50 }
51
52 // Close implements Filer.
53 func (f *OSFiler) Close() (err error) {
54 if f.nest != 0 {
55 return &ErrPERM{(f.Name() + ":Close")}
56 }
57
58 return f.f.Close()
59 }
60
61 // EndUpdate implements Filer.
62 func (f *OSFiler) EndUpdate() (err error) {
63 if f.nest == 0 {
64 return &ErrPERM{(f.Name() + ":EndUpdate")}
65 }
66
67 f.nest--
68 return
69 }
70
71 // Name implements Filer.
72 func (f *OSFiler) Name() string {
73 return f.f.Name()
74 }
75
76 // PunchHole implements Filer.
77 func (f *OSFiler) PunchHole(off, size int64) (err error) {
78 return
79 }
80
81 // ReadAt implements Filer.
82 func (f *OSFiler) ReadAt(b []byte, off int64) (n int, err error) {
83 return f.f.ReadAt(b, off)
84 }
85
86 // Rollback implements Filer.
87 func (f *OSFiler) Rollback() (err error) { return }
88
89 // Size implements Filer.
90 func (f *OSFiler) Size() (n int64, err error) {
91 if f.size < 0 { // boot
92 fi, err := f.f.Stat()
93 if err != nil {
94 return 0, err
95 }
96
97 f.size = fi.Size()
98 }
99 return f.size, nil
100 }
101
102 // Sync implements Filer.
103 func (f *OSFiler) Sync() (err error) {
104 return f.f.Sync()
105 }
106
107 // Truncate implements Filer.
108 func (f *OSFiler) Truncate(size int64) (err error) {
109 if size < 0 {
110 return &ErrINVAL{"Truncate size", size}
111 }
112
113 f.size = size
114 return f.f.Truncate(size)
115 }
116
117 // WriteAt implements Filer.
118 func (f *OSFiler) WriteAt(b []byte, off int64) (n int, err error) {
119 if f.size < 0 { // boot
120 fi, err := os.Stat(f.f.Name())
121 if err != nil {
122 return 0, err
123 }
124
125 f.size = fi.Size()
126 }
127 f.size = mathutil.MaxInt64(f.size, int64(len(b))+off)
128 return f.f.WriteAt(b, off)
129 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 // A basic os.File backed Filer.
5
6 package lldb
7
8 import (
9 "os"
10
11 "github.com/cznic/fileutil"
12 "github.com/cznic/mathutil"
13 )
14
15 var _ Filer = &SimpleFileFiler{} // Ensure SimpleFileFiler is a Filer.
16
17 // SimpleFileFiler is an os.File backed Filer intended for use where structural
18 // consistency can be reached by other means (SimpleFileFiler is for example
19 // wrapped in eg. an RollbackFiler or ACIDFiler0) or where persistence is not
20 // required (temporary/working data sets).
21 //
22 // SimpleFileFiler is the most simple os.File backed Filer implementation as it
23 // does not really implement BeginUpdate and EndUpdate/Rollback in any way
24 // which would protect the structural integrity of data. If misused e.g. as a
25 // real database storage w/o other measures, it can easily cause data loss
26 // when, for example, a power outage occurs or the updating process terminates
27 // abruptly.
28 type SimpleFileFiler struct {
29 file *os.File
30 nest int
31 size int64 // not set if < 0
32 }
33
34 // NewSimpleFileFiler returns a new SimpleFileFiler.
35 func NewSimpleFileFiler(f *os.File) *SimpleFileFiler {
36 return &SimpleFileFiler{file: f, size: -1}
37 }
38
39 // BeginUpdate implements Filer.
40 func (f *SimpleFileFiler) BeginUpdate() error {
41 f.nest++
42 return nil
43 }
44
45 // Close implements Filer.
46 func (f *SimpleFileFiler) Close() (err error) {
47 if f.nest != 0 {
48 return &ErrPERM{(f.Name() + ":Close")}
49 }
50
51 return f.file.Close()
52 }
53
54 // EndUpdate implements Filer.
55 func (f *SimpleFileFiler) EndUpdate() (err error) {
56 if f.nest == 0 {
57 return &ErrPERM{(f.Name() + ":EndUpdate")}
58 }
59
60 f.nest--
61 return
62 }
63
64 // Name implements Filer.
65 func (f *SimpleFileFiler) Name() string {
66 return f.file.Name()
67 }
68
69 // PunchHole implements Filer.
70 func (f *SimpleFileFiler) PunchHole(off, size int64) (err error) {
71 return fileutil.PunchHole(f.file, off, size)
72 }
73
74 // ReadAt implements Filer.
75 func (f *SimpleFileFiler) ReadAt(b []byte, off int64) (n int, err error) {
76 return f.file.ReadAt(b, off)
77 }
78
79 // Rollback implements Filer.
80 func (f *SimpleFileFiler) Rollback() (err error) { return }
81
82 // Size implements Filer.
83 func (f *SimpleFileFiler) Size() (int64, error) {
84 if f.size < 0 { // boot
85 fi, err := os.Stat(f.file.Name())
86 if err != nil {
87 return 0, err
88 }
89
90 f.size = fi.Size()
91 }
92 return f.size, nil
93 }
94
95 // Sync implements Filer.
96 func (f *SimpleFileFiler) Sync() error {
97 return f.file.Sync()
98 }
99
100 // Truncate implements Filer.
101 func (f *SimpleFileFiler) Truncate(size int64) (err error) {
102 if size < 0 {
103 return &ErrINVAL{"Truncate size", size}
104 }
105
106 f.size = size
107 return f.file.Truncate(size)
108 }
109
110 // WriteAt implements Filer.
111 func (f *SimpleFileFiler) WriteAt(b []byte, off int64) (n int, err error) {
112 if f.size < 0 { // boot
113 fi, err := os.Stat(f.file.Name())
114 if err != nil {
115 return 0, err
116 }
117
118 f.size = fi.Size()
119 }
120 f.size = mathutil.MaxInt64(f.size, int64(len(b))+off)
121 return f.file.WriteAt(b, off)
122 }
0 login: 
1 case '\7': *((char *)(384*1024L+062)) = 2; /* beep */
2 Welcome to VAX/VMS Version 1.60
3 ON ENDFILE(SYSIN) GO TO ADATHIBA; /* FILE-VEGE VIZSGALATA */
4 Tape dump of all filesystems taken this afternoon.
5 "Analysis" is "design" spelled backwards.
6 "RULE 7: Option arguments cannot be optional." Sys V Interface p 343.
7 "Sound advice" is usually mostly sound with not much advice.
8 "The Dresser," first a play, then a movie, then AT&T headquarters.
9 "The more you drive ... the less intelligent you are." -- Miller, in Repo Man
10 "x.c", line 1: cannot recover from earlier errors: goodbye!
11 #(cat probably won't work on 8 bit files, you will have to use a simpler filter)
12 $! nulled, predecessor circle
13 $3,000,000
14 %-W-NORML Normal Successful Completion
15 'Tis a gross error, held in schools, That Fortune always favours fools. - John Gay.
16 'Tis better playing with a lion's whelp,/Than with an old one dying.
17 'Tis nobler in the mind to Look Things Up than to Pull Them Out Of The Air.
18 (^|[ (,;])(([Jj]ul[^ ]* *|(07|7)/)0*5)([^0123456789]|$)
19 * UNIX is a Trademark of Bell Laboratories.
20 *** LGP ERROR ***: Initialize -- Cannot initialize graphics hardware device.
21 *** REPLACE THIS LINE WITH YOUR MESSAGE ***
22 -1: No code table for op: ++post
23 ...and on the seventh day, He exited from append mode.
24 /usr/games/fortune: not found
25 /usr/news/gotcha
26 1 bulls, 3 cows
27 127 now in the unregulated subsidiary; see /usr/news/btl-split
28 2 is always smaller than 3, even for large values of 2.
29 2 lacks generality in a way that 1 doesn't.
30 23. ... r-q1
31 355/113 -- not the famous irrational number PI, but an incredible simulation.
32 4.2BSD is like a nightmare about Tenex. - Geoff Collyer
33 4.2BSD may not be a complete disaster, but it does a good job of emulating one.
34 55mph -- It's not a good idea, it's just the law.
35 : is not an identifier
36 A 10.0-szer 0.1 sohasem 1.0!
37 A 6-char limit is like a 6-inch trout: throw it back.
38 A 6-char limit is like night.
39 A Cray is the best machine for simulating the performance of a Cray.
40 A Point is a pair of shorts.
41 A Smith and Wesson beats four aces.
42 A bad workman quarrels with his tools.
43 A big book is a big nuisance. - Callimachus, librarian of Alexandria
44 A billion here, a billion there; soon you're talking real money. -E. Dirksen
45 A bird in hand is safer than one overhead.
46 A bird in the hand is worth what it will bring.
47 A block grant is a nice terminal, but it will keep you awake until noon.
48 A block grant is a solid mass of money surrounded on all sides by governors.
49 A chicken is just an egg's way of making more eggs.
50 A closed mouth gathers no foot.
51 A conservative is one who is too cowardly to fight and too fat to run.
52 A consistent indentation style is the hobgoblin of little minds.
53 A couch is as good as a chair.
54 A coward is one who in a perilous emergency thinks with his legs.
55 A critic is a legless man who teaches running.
56 A day for firm decisions!!!!! Or is it?
57 A day without sunshine is like night.
58 A duck with three wings and a loaf of bread is brother to the sun god.
59 A duck with three wings and a loaf of bread is brother to the turkey.
60 A fly by night leaves no shadow beyond a doubt.
61 A fool and his money stabilize the economy.
62 A foolish consistency is the hobgoblin of little minds.
63 A furore Normanorum libera nos, O Domine!
64 A game, a teaching aid, a sport, and a piece of art. -Erno Rubik
65 A gentleman is one who is never rude unintentionally. -Noel Coward
66 A good memory does not equal pale ink.
67 A good plan today is better than a perfect plan tomorrow.
68 A goodly apple rotten at the heart:/Oh, what a goodly outside falsehood hath!
69 A hacker does for love what others would not do for money.
70 A homeowner's reach should exceed his grasp, or what's a weekend for?
71 A hydrogen bomb doesn't care how brave you are.
72 A hypothesis is an opinion that you are trying to prove true.
73 A journey of a thousand miles begins with a cash advance from Sam.
74 A king's castle is his home.
75 A liberal is one too open-minded to take his own side in an argument.
76 A lone dime always gets the number nearly right.
77 A man does not attain the status of Galileo merely because he is persecuted; he must also be right. -Stephen Jay Gould
78 A man must destroy himself before others can destroy him. -Mong Tse
79 A man who fishes for marlin in ponds will put his money in Etruscan bonds.
80 A man who turns green has eschewed protein.
81 A man with 3 wings and a dictionary is cousin to the turkey.
82 A man without a faith is like a fish without a bicycle.
83 A megabyte here, a megabyte there, and pretty soon you're talking real power.
84 A megaflop is a failure of gigantic proportions.
85 A mighty maze! but not without a plan. -Pope
86 A more wretched hive of scum and villainy: not found.
87 A movie studio is the best toy a boy ever had. -Orson Welles
88 A penny saved is a political breakthrough.
89 A penny saved is ridiculous.
90 A penny saved kills your career in the Pentagon.
91 A philosopher does not need a torch to gather glow-worms by at mid-day. -- Earnest Bramah
92 A plague o' both your houses! They have made worms' meat of me.
93 A plucked goose doesn't lay golden eggs.
94 A poet who reads his verse in public may have other nasty habits.
95 A professor is one who talks in someone else's sleep.
96 A radical is a person with both feet firmly planted in the air.
97 A real Initiation never ends. -Aleister Crowley
98 A really busy person never knows how much he weighs. -Edgar Watson Howe
99 A recently completed trial proved TOAD Generic 1 to be reliable, user-friendly, and convenient.
100 A resort area will be part of your next holiday plans
101 A rolling stone gathers momentum.
102 A rose by any other name would still have thorns.
103 A sharp tongue is the only edge tool that grows keener with constant use. -W. Irving
104 A song in time is worth a dime.
105 A stitch in time keeps your tu-tu from becoming a four-four.
106 A system programmer is someone who debugs his programs with an oscilloscope.
107 A theory is better than an explanation.
108 A thousand throats may be slit in one night by a running man.
109 A tree is best measured when it is down.
110 A truly wise man never plays leapfrog with a Unicorn.
111 A twisting road will take you to Warsaw, but you won't be bored.
112 A u.f.o. closely encountered is no longer a u.f.o.
113 A victory is the greatest tragedy in the world - except a defeat. -Wellington
114 A watched terminal never prints.
115 A wise man never tries to warm himself in front of a painting of a fire.
116 A witty saying means nothing. -Voltaire
117 A woman is only a woman, but a good cigar is a smoke. -Rudyard Kipling
118 A578 Your FLP overflows into your KBUF.
119 AAAOO OOZOR AZZAZ ZAIEO AZAEI IIOZA KHOEO OOYTH OEAZA EAOOZ AKHOZ AKHEY THXAA LETHX KH
120 Ablata at alba.
121 Abortion and suicide are hereditary only if you prevent them.
122 About all some parents accomplish in life is either illegal, immoral or fattening.
123 About all some parents accomplish in life is to send a child to Harvard.
124 About the only thing on a farm that has an easy time is the dog.
125 Absence is better than a cure.
126 Absinthe makes the heart grow fonder.
127 According to the latest official figures, 43% of all statistics are worthless.
128 Accounting software is structured as a set of tools that can be used to build accounting systems.
129 Ad pulchritudinem tria requiruntur; integritas, consonantia, claritas. -Aquinas
130 Admiration is our polite recognition of another's resemblance to ourselves.
131 After 24 hours, corpses and guests smell bad.
132 After all, a murderer is only an extroverted suicide.
133 Afternoon very favorable for romance. Try a single person for a change.
134 Again, and strongly, undress the sheep. It is getting to visitors.
135 All articles that coruscate with resplendence are not truly aurifers.
136 All dare to write, who can or cannot read. -Horace, `Epistles', Book II
137 All my men wear badges, or they wear nothing at all.
138 All of the bridges between our today and our yesteryear have been burnt.
139 All of these futures having been sold, this fortune appears as a matter of record only.
140 All syllogisms have three parts; therefore this is not a syllogism.
141 All that does not glitter is not not-gold.
142 All the ethics in Hollywood can be rolled up and fit into a gnat's navel.
143 All the good ones are taken.
144 All the great men are dead and I'm not feeling too well myself.
145 All things considered, life is 9-to-5 against.
146 All things that are, are lights.
147 All you need to know is in the manual.
148 Almost all good computer programs contain at least one random-number generator.
149 Always keep a record of data. It indicates you've been working.
150 Always make water when you can. -Wellington
151 America's best buy for a dime is a telephone call to the right person.
152 An Austrian army, awfully arrayed, Boldly by battery besieged Belgrade.
153 An airplane is in your future.
154 An artist is never ahead of his time, but most people are far behind theirs. - Varese
155 An asylum for the sane would be empty in America.
156 An atheist is a man with no invisible means of support.
157 An elephant is a mouse built to government specifications.
158 An elephant is a mouse with an operating system.
159 An idle mind is worth two in the bush.
160 An oscilloscope is what cavemen used to debug fire. -Jim Veres
161 An ounce of application is worth a ton of abstraction.
162 And I alone am returned to wag the tail.
163 And malt does more than Milton can/to justify God's ways to man -A.E. Housman
164 And so to bed.
165 Androgyny recapitulates philately.
166 Another good night not to sleep in a eucalyptus tree.
167 Any change or reform you make is going to have consequences you don't like.
168 Any clod can have the facts, but having opinions is an *art*. -Chas. McCabe
169 Any country with "democratic" in the title isn't.
170 Any fool can paint a picture, but it takes a wise person to be able to sell it.
171 Any man's speeding ticket on the Interstate diminishes me, for I am involved in mankind.
172 Any small object that is accidentally dropped will hide under a larger object.
173 Any sufficiently advanced technology is indistinguishable from a rigged demo.
174 Any sufficiently advanced technology is indistinguishable from magic. -Clarke
175 Anyone can win, unless there happens to be a second entry.
176 Anyone who buys Wisconsin cheese is a traitor to mankind! -J. Pournelle
177 Anyone who understands my music will never be unhappy again. -L. Van Beethoven
178 Anyone's life is incomplete unless they are, in some smaller or larger way, saving the world.
179 Anything good in life is either illegal, immoral or fattening.
180 Arabic is a language, Persian is a sweetmeat, and Turkish is an art.
181 Arabic is a mystery -- love is just a crock.
182 Are we not men?
183 Are you kidding?
184 Are you sure you want a two dimensional array?
185 Aren't you glad his name wasn't Alexander Graham Klaxon?
186 Aries -- this is your lucky day!
187 Art is merely cheese made visible.
188 Artistic ventures highlighted. Rob a museum.
189 As above, so below.
190 As goatherd learns his trade by goat, so writer learns his trade by wrote.
191 As of Tuesday, C will be flushed in favor of COBOL. Please update all programs.
192 Assassination is the extreme form of censorship.
193 At the feast of souls failure is always the guest of honor.
194 Attend winter sheep meetings. Learning never ends!
195 Auribus teneo lupum.
196 Automating a mess yields an automated mess. -Michael Hammer
197 Ave discordia.
198 Avoid a hasty decision.
199 Avoid reality at all costs.
200 Away put your weapon! I mean you no harm.
201 BLISS is ignorance.
202 Bad taste is timeless.
203 Ban the bomb. Save the world for conventional warfare.
204 Bank error in your favor. Collect $200.
205 Basic is like doing arithmetic with Roman numerals. - MD McIlroy
206 Be sure to evaluate the bird-hand/bush ratio.
207 Be the sea, and see me be.
208 Beauty is only sin deep. H H Munro
209 Beauty is only skin deep, but ugly goes clean to the bone.
210 Beauty times brains equals a constant.
211 Becoming an overnight success usually takes years.
212 Been Transferred Lately?
213 Better be right or your big venture goes wrong. -Resistor color code mnemonic
214 Better to have failed your Wasserman than never to have loved at all.
215 Between the idea and the reality, between the motion and the act falls the shadow.
216 Beware -- local customs vary. Check with a native before going into the jungle.
217 Beware of a dark-haired man with a loud tie.
218 Beware of low-flying butterflies.
219 Beware the foot of Nessus!
220 Beware: the light at the end of the tunnel may be New Jersey.
221 Beyond a certain point, the whole universe becomes a continuous Initiation.
222 Bigamy is having one spouse too many. Monogamy is the same.
223 Biggus Diggus wants YOU.
224 Bignose from Winnetka.
225 Blessed St. Leibowitz, let them keep on dreamin' down there...
226 Blessed are the meek for they shall inhibit the earth.
227 Blessed are they who Go Around in Circles, for they Shall be Known as Wheels.
228 Bosses never realize that a bottle neck is always at the top.
229 Bourne again.
230 Brain fried -- core dumped
231 Brashith Alhim
232 Bring your wife or husband and pink slip for the best trade-in deal in town.
233 Bubble bubble, toil and trouble; cast that float into a double.
234 Buick offers inbred american quality. -TV ad
235 Build a better mousetrap, and nature will build a better mouse.
236 Build it so that even a fool can use it, and only a fool will want to use it.
237 Bus error -- core dumped
238 But he who kisses the joy as it flies/Lives in Eternity's sunrise. -Wm. Blake
239 But many are not capable of a firm persuasion of anything. -Wm. Blake
240 But you'll never become a rhinoceros...you haven't got the vocation!
241 But, Siriusly...
242 By failing to prepare, you are preparing to fail.
243 By omnibus I traveled to Brooklyn.
244 By the pricking of my thumbs,/Something wicked this way comes.
245 C'est CHouette. Swiss bumper sticker
246 C'est dommage, mais c'est vrai.
247 C'est magnifique, mais ce n'est pas Unix. -Henry Spencer
248 CB is a great place to work. There are so many good going away parties.
249 CB is a many gendered thing.
250 California is a fine place to live if you happen to be an orange. - Fred Allen
251 Campus Crusade for Cthulhu -- It found me.
252 Can all this just be an accident? Or could there be some alien intelligence behind it?
253 Can tomorrow be more than just the end of today?
254 Cannot fork -- try again.
255 Capitalism is indeed obsessed with money, but Marxism is obsessed with Marxism.
256 Captain Clark welcomes you aboard.
257 Caught in --More-- loop.
258 Caution -- be sure brain is engaged before putting mouth in gear.
259 Caution: Do not view laser light with remaining eye.
260 Caution: breathing may be hazardous to your health.
261 Celebrate Hannibal Day this year. Take an elephant to lunch.
262 Celibacy is not hereditary.
263 Center 1127 -- It's not just a job, it's an adventure!
264 Center meeting at 4pm in 2C-543
265 Centran manuals are available in 2B-515.
266 Charlie don't surf.
267 Children are hereditary: if your parents didn't have any, neither will you.
268 Clothes make the man. Naked people have little or no influence on society.
269 Club sandwiches, not baby seals.
270 Cocaine is nature's way of saying you make too much money.
271 Cogito Ergo Spud.
272 Cogito cogito ergo cogito sum.
273 Colorless green ideas sleep furiously.
274 Communication is only possible between equals.
275 Computers are not intelligent. They only think they are.
276 Consistency is always easier to defend than correctness.
277 Constants aren't. Variables don't. LISP does. Functions won't. Bytes do.
278 Contains no kung fu, car chases or decapitations.
279 Continental Life. Why do you ask?
280 Convictions cause convicts -- what you believe imprisons you.
281 Core Error - Bus Dumped
282 Could not open 2147478952 framebuffers.
283 Courage is something you can never totally own or totally lose.
284 Cowards die many times before their deaths;/The valiant never taste of death but once.
285 Crazee Edeee, his prices are INSANE!!!
286 Creativity is no substitute for knowing what you are doing.
287 Creditors have much better memories than debtors.
288 Critics are like eunuchs in a harem: they know how it's done, they've seen it done every day, but they're unable to do it themselves. -Brendan Behan
289 Cthulhu Saves! ... in case He's hungry later.
290 Dames is like streetcars -- The oceans is full of 'em. -Archie Bunker
291 Dames lie about anything - just for practice. -Raymond Chandler
292 Damn it, i gotta get outta here!
293 Dangerous knowledge is a little thing.
294 Data potato, du wop du wop.
295 Day of inquiry. You will be subpoenaed.
296 De minimis non curat lex.
297 Death is nature's way of telling you to slow down.
298 Death to all fanatics!
299 Deep down, we all need that escape velocity. -Steven Spielberg.
300 Democracy is also a form of worship. It is the worship of Jackals by Jackasses.
301 Department meeting in 3 minutes.
302 Deprive a mirror of its silver and even the Czar won't see his face.
303 Der Herrgott wurfelt nicht. -A. Einstein
304 Did you know ... that no-one ever reads these things?
305 Did you know that clones never use mirrors?
306 Die ich rief, die Geister, / Werd ich nun nicht los.
307 Die: to stop sinning suddenly.
308 Dieux! Un monstre hideux. En hurlant. Nous poursuit.
309 Diplomacy is the art of saying "nice doggy" until you can find a rock.
310 Disco delenda est.
311 Disk crisis, please clean up!
312 Disobedience was Man's Original Virtue. -Oscar Wilde.
313 Distrust yourself, and sleep before you fight. 'Tis not too late tomorrow to be brave. - J. Armstrong.
314 Ditat Deus.
315 Do not believe in miracles -- rely on them.
316 Do not clog intellect's sluices with bits of knowledge of questionable uses.
317 Do not confuse boredom with security.
318 Do not confuse effort with work.
319 Do not drink coffee in early A.M. It will keep you awake until noon.
320 Do not go gentle into that good night/Rage, rage against the dying of the light
321 Do not meddle in the affairs of troff; it is subtle and quick to anger.
322 Do not meddle in the affairs of wizards: it makes them soggy and hard to light.
323 Do not meddle in the affairs of wizards: they are subtle and quick to anger.
324 Do not meddle in the mouth.
325 Do not sleep in a eucalyptus tree tonight.
326 Do not take life too seriously; you will never get out if it alive.
327 Do not throw butts in the urinal: it makes them soggy and hard to light.
328 Do not throw butts in the urinal: they are subtle and quick to anger.
329 Do not underestimate the power of the Force.
330 Do not use the blue keys on this terminal.
331 Do something unusual today. Pay a bill.
332 Do what comes naturally now. Seethe and fume and throw a tantrum.
333 Do what thou wilt shall be the whole of the law.
334 Does George know what he's got here? -Steven Spielberg.
335 Does a firm persuasion that a thing is so make it so? -Wm. Blake
336 Does the early bird enjoy the worm as much as the late bird enjoys the sleep?
337 Don't be overly suspicious where it's not warranted.
338 Don't believe everything you hear or anything you say.
339 Don't call me a mindless philosopher, you overweight glob of grease.
340 Don't commute, communicate.
341 Don't conscience-stricken before they're hatched.
342 Don't eat yellow snow.
343 Don't feed the bats tonight.
344 Don't force it, use a bigger hammer.
345 Don't forget to run "make depend"
346 Don't get mad, make book.
347 Don't go surfing in South Dakota for a while.
348 Don't hate yourself in the morning -- sleep till noon.
349 Don't kiss an elephant on the lips today.
350 Don't let your thoughts get in a rut. The knife which spreads may also cut.
351 Don't lie if you don't have to. -Leo Szilard
352 Don't look back -- something may be gaining on you. -Satchel Paige.
353 Don't play games with me. You weren't on any mercy mission this time.
354 Don't put a loaded rifle on the stage unless someone intends to fire it.
355 Don't rely on your nose -- TEST ATMOSPHERE!
356 Don't speak about Time, until you have spoken to him.
357 Don't tell any big lies today. Small ones can be just as effective.
358 Don't try to have the last word. You might get it.
359 Don't try to out-weird me, I get stranger things than you free with my breakfast cereal.
360 Don't type so hard.
361 Don't vote -- it only encourages them.
362 Don't worry -- dat mine, it can't hurt us -- it's one of ours. -Eccles
363 Don't worry if it doesn't work right; if everything did, you'd be out of a job.
364 Don't worry, it's not loaded.
365 Don't worry, they couldn't hit an elephant at this dist
366 Don't you feel more like you do now than you did when you came in?
367 Don't you have anything better to do with your time?
368 Down with categorical imperative!
369 Dreams are free, but there's a small charge for alterations.
370 Dreams are free, but you get soaked on the connect time.
371 Drive defensively, buy a tank.
372 Ducking for apples. Change one letter and it's the story of my life. _ Dorothy Parker
373 Dump time is unreasonable
374 During 1986, UNIX will dominate the low end. J. Scanlon
375 Dyslexics of the world, untie!
376 E Pluribus Unix.
377 E Unibus Plurum.
378 E pur si muove.
379 ERROR CREEPOUT HAS BEGUN
380 EVACUATION ROUTE ---->
381 Each man's death diminishes me for I am involved in Humanity. -John Donne
382 Easy for you to type, I have to do all the work.
383 Eat snart foobs. -Unknown Jerome
384 Economic analysts say that while the economy may be slowing, it is not fizzling out.
385 Edinburgh is the Reykjavik of the South.
386 Ego sum ens omnipotens.
387 Eileen L. Behr has translated her skill in public speaking into a successful career selling capacitors.
388 Either I'm dead or my watch has stopped. -Groucho Marx' last words
389 Either we are alone or we are not. Either way is mind-boggling.
390 Eleemosynary deeds have their incipience intramurally.
391 English is a stretch language; one size fits all. -W. Safire
392 Eschew the implement of correction and vitiate the scion.
393 Espanol tiene demasiada mucha grammatica.
394 Even a cabbage may look at a king.
395 Even a hawk is an eagle among crows.
396 Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley
397 Even paranoia can sometimes be taken to extremes.
398 Even the boldest zebra fears the hungry lion.
399 Even the simplest solution is bound to have something wrong with it.
400 Even the smallest candle burns brighter in the dark.
401 Even the thousand-zloty note can't tapdance.
402 Even these days, it's not as easy to go crazy as you think.
403 Ever see what ratfor does on a syntax error in a for loop?
404 Ever wake up feeling like a null pointer? -Allan Pratt
405 Every absurdity has a champion to defend it.
406 Every cloud has a silver lining; you should have sold it, and bought titanium.
407 Every day, thousands of housewives pick up speed.
408 Every excess becomes a vice.
409 Every good subversive does it for fun. -Rich Rosen
410 Every law creates a whole new criminal class overnight.
411 Every little picofarad has a nanohenry all its own.
412 Every purchase has its price.
413 Every solution breeds new problems.
414 Every time you make something foolproof, along comes a better class of fool.
415 Everybody should believe in something -- I believe I'll have another drink.
416 Everything breaks down.
417 Everything east of the San Andreas Fault will eventually plunge into the ocean.
418 Everything is funny so long as it is happening to someone else. -Will Rogers
419 Everything should be as simple as possible, but no simpler. - A. Einstein
420 Everything takes longer than you think.
421 Everything you know is wrong.
422 Everything's been said before, but nobody's listening, so keep repeating.
423 Ewige Blumenkraft.
424 Excellent day for drinking heavily. Spike the office water cooler.
425 Excellent day to have a rotten day.
426 Excellent time to become a missing person.
427 Executive ability is in your make-up.
428 Exercise is the Yuppie version of bulemia.
429 Exhibition will continue to decline and ultimately lead to other sources of entertainment.
430 Expansion means complexity; and complexity decay.
431 Expected arrival date is presently unknown. -Dave Kristol
432 Experience varies directly with the equipment ruined.
433 Explicit liber viri elephantini.
434 External Security:
435 FORTRAN 8X combines the simplicity of PL/I and the parsimony of ADA. -S Feldman
436 Fact without theory is trivia, theory without fact is bullshit.
437 Facta, non verba -- et verbum caro factus est.
438 Facta, non verba.
439 Fairness? Decency? How can you expect fairness and decency on a planet of sleeping people?
440 Far duller than a serpent's tooth it is to spend a quiet youth.
441 Far too noisy, my dear Mozart. Far too many notes. -Emperor Ferdinand.
442 Favor negative lobes.
443 Fear is failure and the forerunner of failure.
444 Fear not, the end of the world isn't until next week.
445 Few things are harder to put up with than the annoyance of a good example.
446 Fiat lux.
447 Fiat voluntas tua.
448 Fill what's empty; empty what's full; scratch where it itches. -Alice Roosevelt Longworth
449 Find the enemy and shoot him down; everything else is rubbish. -M. von Richthofen
450 Fine day to throw a party. Throw him as far as you can.
451 Fine day to work off excess energy. Steal something heavy.
452 First there is a mountain, then there is no mountain, then there is.
453 First things first. Why not send for the Nazis right now.
454 Fleas can be taught nearly anything that a congressperson can.
455 Flee at once, all is discovered.
456 Flight 23 is down in the Bermuda Triangle.
457 Florida is the "flea and tick capital of America."
458 Fnord.
459 For a good time, call 8367-3100.
460 For every action there is an equal and opposite government program.
461 For me, UNIX is a way of being. -Armando P. Stettner
462 For people who like that kind of book, that is the kind of book they will like.
463 Forget it, Jake...it's Chinatown.
464 Forsan et haec olim meminisse juvabit.
465 Fortis fortuna adiuvat. - Terence
466 Fortran est; non potest legi.
467 Fortunate are they who can laugh at themselves; they will never want for amusement.
468 Fortune, good night, smile once more, turn thy wheel! - King Lear II.ii.180
469 Fortunes ... come tumbling into some men's laps. - Francis Bacon.
470 Frankly, I'd rather be in Philadelphia.
471 Freedom is the right to be our own potty little selves. -G. K. Chesterton
472 Freedom of incrustations of grime is contiguous with rectitude.
473 Friends come and go, but enemies accumulate.
474 Fritter and waste the hours in an offhand way.
475 From EXPLMY: Serious internal error, check the error code in the documentation of VRFYMY.
476 Future looks spotty. You will spill soup in late evening.
477 Gaffer's tape, like The Force, has a light and a dark side and binds the universe together.
478 Gallium Arsenide is the material of the future and it always will be.
479 Generalizations are useful. The work contained in them can be reckoned as labor and therefore can create value. -G.W. Hegel
480 Generosity and perfection are your everlasting goals.
481 Genius is the talent of a person who is dead.
482 Gentlemen, you can't fight here. This is the war room.
483 Get your boots on, 'cause we're gunna go in DEEP!
484 Give me a rock, paper and scissors and I will move the world. CCFestoon
485 Give me a sleeping pill and tell me your troubles.
486 Give your child mental blocks for Christmas.
487 Given enough inside information and unlimited credit, you've got to go broke.
488 Go directly to jail. Do not pass Go, do not collect $200.
489 Go out and see what the real world has to offer -Gerry Todd
490 Go suck on an infinite tube.
491 God does not play dice.
492 God gives us relatives; thank goodness we can choose our friends.
493 God is in the rock too -- in the rock!
494 God isn't dead, he just couldn't find a parking place.
495 God made the integers; all else is the work of Man.
496 God not only plays dice with the universe, He loads the dice too.
497 Gods! A hideous beast, baying is pursuing us!
498 Golden lads and girls all must,/Like chimney sweepers, come to dust.
499 Good Americans, when they die, go to Paris. - Thomas Appleton.
500 Good Rule: Don't put anything in your mouth labeled "HARMFUL IF SWALLOWED"
501 Good day for a change of scene. Repaper the bedroom wall.
502 Good day for flaming at floyd!trb.
503 Good day for overcoming obstacles. Try a steeplechase.
504 Good day to avoid cops. Crawl to work.
505 Good day to do the unexpected: write some documentation.
506 Good day to let down old friends who need help.
507 Good day to write a purchase requisition for a 747.
508 Good fish get dull but sex is always fun. -- Mehinaku proverb
509 Good health is just the slowest, most lingering way of dying.
510 Good intentions don't mean anything unless they can deliver.
511 Good manners and bad breath get you nowhere
512 Good news. Ten weeks from Friday will be a pretty good day.
513 Gort! Klaatu barada...uh...uh...
514 Government expands to absorb all available revenue and then some.
515 Government is just Anarchy's way of making more anarchy.
516 Graecum est; non potest legi.
517 Great shot, kid. That was one in a million.
518 Great warrior? Heh-heh-heh. Wars do not make one great.
519 Green light in A.M. for new projects. Red light in P.M. for traffic tickets.
520 Growth itself becomes the only moral end. -John Dewey
521 Guns don't kill detectives -- love does.
522 Ha! You killed my husband, Sam. Be kind to me.
523 Had Cleopatra's nose been shorter, the whole history of the world would have been different. - Pascal
524 Hail to the sun god/He sure is a fun god/Ra! Ra! Ra!
525 Half Moon tonight. (At least it's better than no Moon at all.)
526 Hang by your pseudopod, write if you find a warm rich planet ripe for conquest.
527 Hang in there, hammock-nose.
528 Hangover is the wrath of the grapes.
529 Have a nice diurnal anomaly.
530 Have you done your Christmas chopping yet? -anon. White House Advisor 12/24/81
531 Have you hugged my T-shirt today?
532 He can't think without his hat.
533 He cried at all his own weddings, and with reason.
534 He gave her a look that you could have poured on a waffle.
535 He is no lawyer who cannot take two sides.
536 He is truly wise who gains wisdom from another's mishap.
537 He is winding the watch of his wit; by and by it will strike.
538 He looked at me as if I was a side dish he hadn't ordered.
539 He missed an invaluable opportunity to hold his tongue.
540 He serves the state best who opposes it most. -Thoreau
541 He that laugheth in the face of death haveth the last laugh.
542 He thinks by infection, catching an opinion like a cold.
543 He was al coltissh, ful of ragerye,/And ful of jargon as a flekke pye. -Chaucer
544 He was so narrow-minded he could see through a keyhole with two eyes.
545 He who binds himself to a joy/Does the winged life destroy. -Wm. Blake
546 He who has a shady past knows that nice guys finish last.
547 He who has imagination without learning has wings but no feet.
548 He who has science and art has religion. -Goethe
549 He who hesitates is last.
550 He who hesitates is scrap metal.
551 He who hesitates is sometimes saved.
552 He who invents adages for others to peruse takes along rowboat when going on cruise.
553 He who keeps his nose to the grindstone, has a flat face.
554 He who laughs last is a little slow on the uptake.
555 He who laughs, lasts.
556 He who listens last is the last one listening.
557 He who makes a beast of himself gets rid of the pain of being a man. -H.S. Thompson
558 He who spends a storm beneath a tree, takes life with a grain of TNT.
559 He who trains his tongue to quote from learned sages will be known far and wide as a smartass.
560 He who wears belt and suspenders needs tighter belt.
561 Help a swallow land at Capistrano.
562 Help conquer the IQ shortage: worry less and think more.
563 Help me, i'm a prisoner in a chinese computer terminal!
564 Hey, I've got it -- let's put on a show!
565 Hi, this is Ken. What's the root password?
566 Hindsight is an exact science.
567 His heart was yours from the first moment that you met.
568 His money is twice tainted: 'taint yours and 'taint mine.
569 History is a race between education and catastrophe. -H. G. Wells
570 Hit space to start
571 Hodie tempum scriptire in Latinum non habeo. Cras epistlum submissibo.
572 Home is the place where, when you have to go there, they have to take you in.
573 Home is where / is.
574 Honi soit la vache qui rit.
575 Hop before you skip.
576 Horse sense is the thing a horse has which keeps it from betting on people.
577 How I want a drink, alcoholic of course, after the chapters involving quantum mechanics.
578 How can I take an interest in my work when I don't like it?
579 How can you work when the system's so crowded?
580 How did the Universe manage to go bang in such an unreasonable way? -PCW Davies
581 How do I love thee? Hand me my calculator...
582 How is it far, if you can think of it?
583 How long you live has nothing to do with how long you are going to be dead.
584 How sharper than a child's tooth it is to have a thankless serpent.
585 How sharper than a serpent's tooth it is to have a thankless child.
586 How the elephant got into my pyjamas I'll never know. -Marx, Animal Crackers
587 How wonderful opera would be if there were no singers.
588 How you look depends on where you go.
589 Human beings are the only animals of which I am thoroughly and cravenly afraid.
590 Human kind cannot bear very much reality. -T.S. Eliot
591 Hypocrisy is the tribute vice pays to virtue.
592 Hypothesize and test.
593 I am Magnus. You are registered in my memory banks...
594 I am a high-pressure guy, and I didn't take this job to conduct a going-out-of-business sale. - A.A. Penzias
595 I am free of the wheel of Maya; I am dead to the dance of life.
596 I am large; I contain multitudes.
597 I am the Supreme Being. I'm not entirely dim.
598 I am the beast, I am the Word of the Aeon...I am a hell of a Holy Guru.
599 I am the wandering glitch -- catch me if you can.
600 I can call spirits from the vasty deep./Why, so can I, or so can any man.
601 I can resist everything except temptation. -Oscar Wilde.
602 I can't decide whether to throw you overboard or just change the way you look.
603 I cannot teach him. The boy has no patience.
604 I contradict myself? Very well, then: I contradict myself. I am large.
605 I dinna believe she'll hold up much longer, Captin.
606 I do not sketch or design a work, I merely begin. -Joan Miro
607 I don't even know what street Canada is on. - Al Capone
608 I don't have a moral plan... I'm a Canadian. -David Cronenberg
609 I don't like to walk, and I don't like to paddle. -James Watt
610 I don't love you any more since you ate my dog.
611 I don't mind your thinking slowly; i mind your publishing faster than you think. -W. Pauli
612 I give presents to the mother, but I think of the daughter.
613 I hate programs that chdir on you - Boyd Roberts
614 I have 36 rolls of 5247 for our use in the laser fridge...
615 I have NEVER written a program in C! Narain Gehani
616 I have discovered the art of deceiving diplomats; I tell them the truth and they never believe me. -Cavour
617 I have everything we will need.
618 I have never let my schooling interfere with my educations.
619 I have nothing to say and I am saying it and that is poetry as I need it. -Cage
620 I have the most perfect confidence in your indiscretion.
621 I haven't lost my mind. I've got it backed up on tape somewhere.
622 I hope that there are sour apples in every bushel.
623 I kissed my first cigarette on the herpolhode lying in the invariable plane.
624 I kissed my first cigarette on the stage unless someone intends to fire it.
625 I kissed my first lady and smoked my first cigarette on the same day. I have never had time for tobacco since. -Arturo Toscanini
626 I know nothing. -Ken Thompson
627 I know the difference between real-real and drug-real.
628 I like user-hostile ignorance-based amateur systems.
629 I like work; it fascinates me; I can sit and look at it for hours.
630 I love Pascal ... I'm also into leather.
631 I love the smell of napalm in the morning.
632 I love you.
633 I must have slipped a disk; my pack hurts.
634 I never dringk ... wine. -Bela Lugosi
635 I never refuse. I never contradict. I sometimes forget. -Disraeli
636 I knew it was coming and I still felt as if I'd swallowed a snowcone whole.
637 I regard an original error as better than a borrowed truth. -Merton.
638 I regard an original error as better than no Moon at all.
639 I see no login here!
640 I see only darkness in the crystal ball
641 I sense something -- a presence I haven't felt since....
642 I taught him everything he knows. Now he knows more. -Randal L. Schwartz
643 I thank you from the heart of my bottom.
644 I think Isaac Newton is doing most of the driving right now.
645 I think my spaceship knows which way to go.
646 I think that I shall never see a billboard as lovely as a tree. -Ogden Nash
647 I think; therefore I am confused.
648 I was just going to call you.
649 I will not suffer fools gladly, but I will gladly make fools suffer. -Bimmler
650 I wish I had time to explain dimensional transcendentalism -Dr. Who
651 I wish you humans would leave me alone.
652 I wonder what will happen if I touch these two wires together.
653 I would be perfectly happy being Kepler, [but] I have been Kepler many times over.-B. Mandelbrot
654 I wouldn't let a knight out on a dog like this!
655 I wouldn't marry her to a ten foot Pole.
656 I wouldn't marry him with a ten foot pole.
657 I'd give my right arm to be ambidextrous.
658 I'd rather have a free bottle in front of me than a pre-frontal lobotomy. -Martin Mull
659 I'd rather have my mail delivered by Lockheed than ride in a plane built by the Post Office.
660 I'll eat it if I'm wrong. I mean a potato. - Danny Sleator
661 I'll produce anything that gets high ratings. -Anonymous NBC official
662 I'll smoke when the pope's wife takes the pill.
663 I'm a Hollywood writer; so I put on a sports jacket and take off my brain.
664 I'm free -- and freedom tastes of reality.
665 I'm from the government, and I'm here to help you.
666 I'm prepared for all emergencies but totally unprepared for everyday life.
667 I'm so hip I have difficulty seeing over my pelvis.
668 I'm sorry, but I've made other plans.
669 I've done this before and never had any trouble.
670 I've got a ferret sticking up my nose.
671 ICIKL: DO I = 1 /* BY +1 FELTETELEZESEVEL */ TO 2*N;
672 IOT trap -- core dumped
673 IOT trap -- core melted
674 If A=B and B=C, then A=C, except where void or prohibited by law. -Roy Santoro
675 If Congress must do a painful thing, it must be done in an odd-numbered year.
676 If God could perform the tricks we do, He'd be a happy man.
677 If God had meant Texans to ski, he would have made bullshit white.
678 If God had wanted you to go around nude, He would have given you bigger hands.
679 If God is perfect, why did He create discontinuous functions?
680 If God lived on Earth, people would knock out all His windows.
681 If God meant for Texans to ski, He would have made them a mountain.
682 If God wanted us to have a President, He would have sent us a candidate.
683 If I could remember the names of all these particles I would have been a botanist. -- Enrico Fermi
684 If I had only known, I would have been a locksmith. -Albert Einstein
685 If I had to choose between System V and 4.2, I'd resign. - Peter Honeyman
686 If I owned Texas and Hell, I'd rent out Texas and live in Hell.
687 If I say it's safe to surf this beach, Captain, it's safe to surf this beach.
688 If I should return in my absence, kindly detain me until I get back.
689 If I wanted your opinion, I'd tell it to you. -Samuel Goldwyn
690 If Lincoln were alive today he would be spinning in his grave. -G. Ford
691 If MS/DOS is the only operating system you're ever going to use, then the procedure is simple
692 If a thousand people say a foolish thing, it remains a foolish thing.
693 If all economists were laid end to end, they would not reach a conclusion.
694 If anything can go wrong, it will.
695 If at first you don't succeed, quit; don't be a nut about success.
696 If at first you succeed, try to hide your astonishment.
697 If bankers can count, why do they have eight windows and only four tellers?
698 If butterflies had teeth like tigers they would never make it out of the hangar.
699 If double-bubble inflation did occur, then the shadow world is exponentially uninteresting.
700 If ever I utter an oath again may my soul be blasted to eternal damnation.
701 If everything is coming your way, you're in the wrong lane.
702 If ignorance were cornflakes, you'd be General Mills.
703 If it ain't broke, don't fix it.
704 If it doesn't matter, it does not matter.
705 If it happens, it must be possible.
706 If it isn't like TECO, it's not worth using. -Rae McLellan
707 If it pours before seven, it has rained by eleven.
708 If it were dangerous they would post a sign...
709 If it's boring, turn it off.
710 If it's gratitude you want, get a dog. -P. T. Barnum
711 If it's not broken, don't fix it.
712 If it's not worth doing, it's not worth doing well.
713 If it's worth doing well, it's worth doing.
714 If more is better then too much is just enough.
715 If music be the breakfast food of love, kindly do not disturb until lunch time.
716 If some day it should happen that a victim must be found, I've got a little list, I've got a little list.
717 If the "medium is the message" then the message of low-bandwidth timesharing is "blah". -- Alan Kay
718 If the check is truly in the mail, it is surely made out to someone else.
719 If the coin is heads up don't pick it up.
720 If the experiment works, you must be using the wrong equipment.
721 If the facts do not support the theory, they must be disposed of.
722 If the government doesn't trust the people, why doesn't it elect a new people?
723 If the shoe fits, buy the other one, too.
724 If there are any resources you need to get this job done, just let us know.
725 If there is no God, who pops up the next Kleenex? -Art Hoppe
726 If they gave me a goldfish, I would cook it. -Feng Jicai
727 If time heals all wounds, how come the belly button stays the same?
728 If voting could change the system, it would be against the law.
729 If we turn on the lights fast enough, we'll see what the dark looks like.
730 If we'd all been living in California, we wouldn't have worked at ALL.
731 If you ask how much it is, you can't afford it.
732 If you can't find enough radiation at Ralph's, you can probably do without it.
733 If you can't stand the heat, remove your clothing!
734 If you cannot convince them, confuse them. -Harry S. Truman
735 If you do a job too well, you'll get stuck with it.
736 If you don't care where you are, then you ain't lost.
737 If you don't insist on correct answers, I can make it run as fast as you want.
738 If you don't know where you're going, it doesn't matter how you get there.
739 If you don't like the weather in New England, just wait a few minutes.
740 If you don't pay attention to every little detail, you miss most of the jokes.
741 If you gaze long enough into the abyss, the abyss will gaze back into you.
742 If you grab the bull by the horns, feathers will fly.
743 If you have to lie to someone, it's their fault.
744 If you have to think twice about it, you're wrong.
745 If you have to travel on the Titanic, why not go first class?
746 If you know high class quality merchandise, you know this is CHEAP!
747 If you start now you might finish on time.
748 If you suspect a man, don't employ him.
749 If you take the last cup, make a new pot.
750 If you take the last pot, make a new cup.
751 If you think before you speak the other guy gets his joke in first.
752 If you think big enough, you'll never have to do it.
753 If you think it's hard going to the moon, you should try staying home.
754 If you think last Tuesday was a drag, wait till you see what happens tomorrow!
755 If you want to go somewhere, goto is the best way to get there. K Thompson
756 If you want to have clean ideas, change them like shirts.
757 If you were able to count up to infinity I'll bet you would never get over it.
758 If you're asked to join a parade, don't march behind the elephants.
759 If you're feeling good, don't worry. You'll get over it.
760 If you're not apprehensive then you don't understand the situation.
761 If you're not part of the solution, you're part of the precipitate.
762 If your experiment needs statistics, you ought to have done a better experiment. - E. Rutherford
763 Ignore alien orders.
764 Ignore previous fortune.
765 Ignore the fatal errors. It's O.K.
766 Il faut cultiver son jardins. -Voltaire
767 Illegal Arbitrator - Line 23
768 Illegitimi non carborundum.
769 Immanuel Kant but Kubla Khan.
770 In Africa the tusks are too firmly rooted, but in Alabama the Tuscaloosa.
771 In addition to a yes and a no, the universe contains a maybe. -D. Finkelstein
772 In an evolving universe, who stands still moves backwards.
773 In any society, the correct pronunciation is the dialect that has an army.
774 In case of fire, stand in the hall and shout "Fire!".
775 In challenging a kzin, a simple scream of rage is sufficient.
776 In communism Man exploits Man. In capitalism it's the other way around.
777 In comparison with the ancients, we stand like dwarfs on the shoulders of giants. -Bernard of Chartres
778 In girum imus nocte et consumimur igni.
779 In marriage, as in war, it is permitted to take every advantage of the enemy.
780 In nature there is immediate adjustment but no compulsion. -Chuang Chou
781 In order to make an omelette, you have to break a few cooks.
782 In rebus mathematicis errores quam minimi non sunt contemnendi.
783 In the Unix tradition, vi is intended to be a small tool that does one thing well.
784 In the future, all programmers will be able to use malloc.
785 In the land of the blind the one-eyed man can see across the road and prove it.
786 In the land of the blind, the one-eyed man is king.
787 In the land of the one-eyed men, the blind have to wear glasses.
788 In this world, truth can wait; she's used to it.
789 Incest, like charity, begins at home.
790 Insanity is always the best defense against boredom.
791 Inside every large problem is a small problem struggling to get out. -N. Wirth
792 Intermittent resolutions lack potency. -Robert Silverberg
793 Into each life a little fallout must rain. -Baba Rebop
794 It got to a point where I had to get a haircut or a violin. -F.D.Roosevelt
795 It is a poor judge who cannot award a prize.
796 It is a tale told by an idiot, full of sound and fury, signifying nothing.
797 It is a very sad thing nowadays that there is so little useless information.
798 It is absurd to deny the role of fantasy in even the strictest science. -Lenin
799 It is bad luck to be superstitious. -Andrew W. Mathis
800 It is better to have loved and lost -- much better.
801 It is better to have loved and lost than just to have lost.
802 It is better to kiss an avocado than to get in a fight with an aardvark.
803 It is better to light a single candle than to curse the darkness, except at the Browns Ferry reactor.
804 It is better to rule in Hell than to serve in Heaven. -Milton
805 It is better to wear out than to rust out.
806 It is easier to get forgiveness than permission.
807 It is far better to vote for a loser than to elect one.
808 It is far better to vote for a loser than to elect?
809 It is fruitless to become lachrymal over precipitately departed lacteal fluid.
810 It is hard to sit with the turkeys when you soar with the eagles.
811 It is much easier to suggest solutions when you know nothing about the problem.
812 It is the business of the future to be dangerous. -Hawkwind
813 It is the wise bird who builds her nest in a tree.
814 It is useless to put on your brakes when you're upside down. -Paul Newman
815 It seems like the less a statesman amounts to, the more he loves the flag.
816 It seems to make an auto driver mad if he misses you.
817 It steam-engines when it becomes steam-engine time. -Charles Fort
818 It takes approximately two minutes to reposition the continents from one geological era to another.
819 It was a book to kill time for those who liked it better dead.
820 It works better if you plug it in.
821 It would appear that even BTL employees put their pants on one leg at a time.
822 It would be wise to cut expectations in half.
823 It's 5 o'clock. Do you know where your files are?
824 It's Your Environment -- Use It Up!
825 It's a hardware problem.
826 It's a sad woman who buys her own perfume.
827 It's a small world, but I'd hate to have to paint it.
828 It's a software problem.
829 It's a useless but absolutely vital precaution.
830 It's an empty head that wears a hairpiece. - Pauline Kael
831 It's business doing pleasure with you.
832 It's clever, but is it art?
833 It's deja vu all over again.
834 It's difficult to explain Kleenex to an aborigine.
835 It's earlier than you think.
836 It's funny how they work so well, even when they're not appropriate.
837 It's hard to be humble when you're perfect.
838 It's hard to be mellow when you bite your nails.
839 It's hard to be mellow when you can't stand up.
840 It's hard to love someone who looks down on you because your hands get bloody protecting him.
841 It's just a silly native superstition.
842 It's later than you think.
843 It's lonely at the top, but it's lonelier at the bottom.
844 It's morally wrong to allow suckers to keep their money.
845 It's not Camelot, but it's not Cleveland, either. -Boston Mayor Kevin White
846 It's not a car, it's a Volkswagen.
847 It's not cool enough for the eighties.
848 It's not easy to play the clown when you've got to run the whole circus.
849 It's not my fault -- it's a mechanical problem!
850 It's not my fault!
851 It's not reality that's important, but how you perceive things.
852 It's not reality that's important, it's how you perceive things.
853 It's not the time between the takes that takes the time - it's changing your mind between the takes that takes the time. -Stage Dept.
854 It's not the time it takes to take the takes that takes the time, it's the time it takes between the takes that takes the time. -S. Spielberg
855 It's not the years, it's the mileage.
856 It's only a game!
857 It's simple, clean, it works, and you can get it right now. -Mike O'Dell
858 It's some kind of instinct...This was an important place in their lives.
859 It's the law: Use a pun, go to prism (for minor refractions of the law only!)
860 It's the thought, if any, that counts! -Dick Grantges
861 It's time to gearshift up from the crawl we've been in to a full trot. - Jack Scanlon
862 It's worse than being at the theatre.
863 Jam tomorrow and jam yesterday -- but never jam today.
864 Jesus Rodrigues has a 9-inch duck.
865 Jesus saves, Moses invests, the Mongol Hoards, but only Buddha pays dividends.
866 Join me and I will complete your training.
867 Journalism will kill you, but it will keep you alive while you're at it.
868 Just be glad you don't get all the government you pay for. -Will Rogers
869 Just because you're paranoid doesn't mean they're not out to get you.
870 Justice for the poor is much less popular than revenge on the rich.
871 Keep emotionally active. Cater to your favorite neurosis.
872 Ken Thompson can't beat Belle. So what? How fast can Seymour Cray add?
873 Kids are always the only future the human race has. -William Saroyan
874 Kill ugly radio!
875 Klaatu barada nikto.
876 Kleeneliness is next to Goedeliness.
877 Label on a bottle of pills: "Do not take these pills if this label is missing"
878 Lack of leadership is no substitute for inaction.
879 Lando's not a system, he's a man. He's a gambler, scoundrel. You'd like him.
880 Language is a virus from outer space. -William Burroughs.
881 Language is all that separates us from the lower animals and the bureaucrats.
882 Last login: Sat Aug 10 09:22:14 on ttym0
883 Laugh and the world laughs with you; snore and you sleep alone.
884 Laugh, and the world ignores you. Crying doesn't help either.
885 Lay on, MacDuff, and curs'd be him who first cries, `Hold, enough!'
886 Leadership means taxes.
887 Lest men suspect your tale untrue,/Keep probability in view. -John Gay (1727)
888 Let a fool hold his tongue and he will pass for a sage.
889 Let him who takes the Plunge remember to return it by Tuesday.
890 Let no one unskilled in geometry enter here. -Plato
891 Let not the sands of time get in your lunch.
892 Let sleeping wraiths lie.
893 Let's just take this shortcut across this field. That bull doesn't see us.
894 Let's look at the record. -Al Smith
895 Li'l dollink, always fetful.
896 Liar: One who tells an unpleasant truth.
897 Life is a game: whoever dies with the most toys wins.
898 Life is a giant shell and we're just processes.
899 Life is a mystery -- love is a dancer.
900 Life is a yo-yo, and mankind ties knots in the string.
901 Life is hard but unjust.
902 Life is just a bowl.
903 Life is not for everyone. -M. O'Donoghue
904 Life is what happens to you while you're busy making other plans.
905 Like winter snow on summer lawn, time past is time gone.
906 Little girls have pretty curls, but I like Oreos.
907 Little things come in small packages.
908 Live forever, or die trying.
909 Live long and perspire.
910 Living in the past has one thing in its favour - it's cheaper.
911 Load average too high now (11.358253), please try later
912 Local disks are our FORTRAN. -Warren Teitelman
913 Long computations which yield 0 (zero) are probably all for naught.
914 Longevity is an optimist's heaven and a pessimist's hell.
915 Look after the molehills and the mountains will look after themselves.
916 Look on my works, oh ye mighty, and giggle.
917 Lord? We don't have no lord. We're an anarcho-syndicalist commune.
918 Lose a few, lose a few.
919 Losing your servo track is just God's way of saying `BOOGA, BOOGA!'
920 Love and scandal are the best sweeteners of tea.
921 Love is a many gendered thing.
922 Love is in the offing, said the homicidal maniac.
923 Love is only love, but money is forever.
924 Love the sea? I dote upon it - from the beach.
925 Love, and do what thou wilt.
926 Luchamos contra el Wombat, otra enemigo de la humanidad. -Frente Wombato de Liberacion Nacional
927 Luke, don't give in to hate. That leads to the dark side.
928 MOUNT TAPE U1439 ON B3, NO RING
929 Machne oprating at olny tn prcnt eficiency.
930 Macro context switch under way, please do not log out!
931 Make War, not Love: killing is fun too. -Nicholas von Hoffman
932 Make a list of all the facts you know about the universe.
933 Make is like Pascal: everybody likes it, so they go in and change it. -DM Ritchie
934 Make use of whatever advanced technology is available
935 Make: Don't know how to make love. Stop.
936 Making outside money using our computers has resulted in suspension.
937 Making sense makes more sense than not making sense. -T. Duff
938 Male tyrannosaurs may have used their diminutive front legs to titillate female partners, but this will not explain why they got so small. - Gould and Lewontin
939 Man cannot live by bread alone: frequently, there must be beverage, too.
940 Man cannot live by bread alone; he needs a little peanut butter on it.
941 Man has created death. -William Butler Yeats
942 Man is in doubt to deem himself a god or beast. -Alexander Pope
943 Man is in session.
944 Man who falls in vat of molten optical glass makes spectacle of self.
945 Man's horizons are bounded by his vision.
946 Many are called, few are chosen. Fewer still get to do the choosing.
947 Many are called, few volunteer.
948 Many are cold, but few are frozen.
949 Many pages make a thick book.
950 Marriage is a ghastly public confession of a strictly private intention.
951 Marriage is an attempt to change a night owl into a homing pigeon.
952 Masterpieces make their own rules.
953 May I have a large container of coffee?
954 May the bluebird of happiness twiddle your bits.
955 May you live all the days of your life.
956 May your rolling stone always grow grass that is greener underneath.
957 Maybe I should have screwed up. - Ken Thompson
958 Mcc may be slow and generate bad code, but it took a long time to develop.
959 Medeis ageometretos eisito mou ten stegen. -Plato
960 Members of an avian species of identical plumage congregate.
961 Men seldom make passes at girls who wear glasses. -Dorothy Parker.
962 Men seldom show dimples to girls who have pimples.
963 Message will arrive in the mail. Destroy, before the FBI sees it.
964 Micronics makes it simple.
965 Might as well be frank, monsieur. It would take a miracle to get you out of Casablanca.
966 Military justice is to justice as military music is to music. -Clemenceau
967 Military music is to music as military intelligence is to intelligence
968 Mind your own business, Spock. I'm sick of your halfbreed interference.
969 Misery loves company, but company does not reciprocate.
970 Misfortunes arrive on wings and leave on foot.
971 Mistakes are oft the stepping stones to failure.
972 Money cannot buy happiness, but happiness will not buy groceries.
973 Money is a terrible thing to follow but a charming thing to meet.
974 Money is the root of all evil, and man needs roots.
975 Money may buy friendship but money can not buy love.
976 Money will say more in one moment than the most eloquent lover can in years.
977 Most sacrilegious murder hath broke ope/The Lord's anointed temple. -MacBeth
978 Most users are within a 10 mile radius.
979 Mr. President! We cannot allow ... a MINE-SHAFT GAP!
980 Multi sunt vocati, pauci vero electi.
981 Multilevel standards are like onions. They're smelly and make you cry a lot. -Ron Natalie
982 My broker is E. F. Hutton, and E. F. Hutton says...
983 My karma just ran over your dogma.
984 My program is so jammed with clever tricks - GJ Holzmann
985 My way of joking is to tell the truth; it's the funniest joke in the world.
986 NOT NOT NOT ALLOWED
987 Naked is the best disguise.
988 National security is the chief cause of national insecurity.
989 Need a personal problem? Get a personal computer. - C. P. Killian
990 Neither a borrower nor a lender be/For loan oft loses both itself and friend.
991 Nembutal numbs it all, but I prefer alcohol. -Strummer/Jones
992 Netnews is someone yelling "Anybody wanna buy a used car?" in a crowded theater.
993 Never argue with a fool -- people might not know the difference.
994 Never attribute to malice what can be found in scientific american, under computer recreations.
995 Never buy a case of wine with eleven bottles.
996 Never call a man a fool. Borrow from him.
997 Never eat anything bigger than your head.
998 Never eat in a restaurant that rotates or is above the 10th floor.
999 Never eat rutabaga on any day of the week that has a "y" in it.
1000 Never give a inch!
1001 Never hatchet your Counts before they chicken.
1002 Never lick a gift horse in the mouth.
1003 Never put off till tomorrow what you can avoid altogether.
1004 Never speak ill of yourself; your friends will always say enough on that subject.
1005 Never stow away on a kamikaze plane.
1006 Never worry the boss unnecessarily. Don't tell him.
1007 New career ideas are worth pursuing.
1008 New crypt. See /usr/news/crypt.
1009 Niagara Falls is the second-biggest disappointment in a bride's life. -O. Wilde
1010 Niagara Falls is the wise bird who builds her nest in a chinese computer terminal!
1011 Niagara Falls would be much more impressive if it flowed the other way. - Oscar Wilde
1012 Nihilism means nothing to the dancing peasants.
1013 Nihilism should commence with oneself.
1014 No amount of genius can overcome a preoccupation with detail.
1015 No branch is better than its trunk.
1016 No directory
1017 No directory! Logging in with home=/
1018 No good deed goes unpunished. -Clare Booth Luce.
1019 No jaggies!
1020 No man's life, liberty or property are safe while the legislature is in session.
1021 No mistake is too small to be fixed, but first make sure it's a mistake.
1022 No news is good news.
1023 No note is too high to be taken down an octave.
1024 No one can feel as helpless as the owner of a sick goldfish.
1025 No two ways about it, there are two sides to every story.
1026 No user jobs will be lost because of the crash.
1027 Nobody can be as agreeable as an uninvited guest.
1028 Nobody expects the Spanish Inquisition!
1029 Nobody goes to the theatre unless suffering from acute bronchitis.
1030 Nobody is truly sane until he feels gratitude to the whole universe.
1031 Nobody knows anything, or if they do, they are careful to hide the fact.
1032 Nobody takes computer graphics seriously, even the guys that do it. -T. Duff
1033 Non serviam.
1034 Nostalgia isn't what it used to be.
1035 Not all the water in a rough rude sea/Can wash the balm from an anointed king.
1036 Not only is there no God, but try getting a plumber on Sundays.
1037 Nothing astonishes men so much as common sense and plain dealing.
1038 Nothing difficult is ever easy. -Steve Falco
1039 Nothing is as easy as it looks.
1040 Nothing is capable of being well set to music that is not nonsense. - Joseph Addison.
1041 Nothing is impossible for the man who doesn't have to do it himself.
1042 Nothing is impossible for the man who will not listen to reason.
1043 Nothing is true. Everything is permissible. -Hassan i Sabbah
1044 Nothing matters indeed, it's all in your mind...
1045 Nothing more certain than incertainties; Fortune is full of fresh variety: Constant in nothing but inconstancy. - Richard Barnfield.
1046 Nothing of interest ever happened on this day.
1047 Nothing works. No one knows why. And some jerk is talking French. -Bob Lied
1048 Now and then an innocent man is sent to the legislature.
1049 Now is the winter of our discontent, made glorious summer in Northern California.
1050 Now is the winter of our discontent/Made glorious summer by this sun of York.
1051 O brave new world,/That has such people in't!
1052 O dear Ophelia! I am ill at these numbers: I have not art to reckon my groans.
1053 O.T.O. wants you.
1054 OK, I think I understand.
1055 OS 360 -- Not uranium.
1056 Of all forms of caution, caution in love is the most fatal.
1057 Of all things man is the measure. -Protagoras
1058 Oh, don't the days seem lank and long, when all goes right and nothing goes wrong.
1059 Oh, so there you are!
1060 Old MacDonald had an agricultural real estate tax abatement.
1061 Old age -- it's the only disease that you don't look forward to being cured of.
1062 Omnibus ex nihil ducendis sufficit unum. -Gottfried Wilhelm von Leibniz
1063 On a clear disk you can seek forever.
1064 Once TOAD is operational, how frequently would you expect to access TOAD?
1065 One Bell System -- it sometimes works.
1066 One Bell System -- it works.
1067 One bad apple can ruin a snake.
1068 One horse-laugh is worth ten thousand syllogisms. -H. L. Mencken
1069 One man tells a falsehood, a hundred repeat it as true.
1070 One man's Mede is another man's Persian.
1071 One picture is worth 128k words.
1072 One scythe fits all.
1073 One starts life with a swelled head and ends with swelled feet. -Ezra Pound
1074 Only %d shopping days until Christmas.
1075 Only God can make a random selection.
1076 Only someone with nothing to be sorry for smiles back at the rear of an elephant.
1077 Only two things are infinite: the universe and human ignorance. -A. Einstein
1078 Ontogeny recapitulates phylogeny, or is that ontology recapitulates philology?
1079 Ontogeny recapitulates phylogeny. -Haeckel
1080 Ontogeny rehashes phylogeny.
1081 Ooh, Andy Tannenbaum? His netnews is SO derivative.
1082 Options can cause undesirable operations, so it is important to ensure they are set up properly.
1083 Order ignorant aliens.
1084 Others will look to you for stability, so hide when you bite your nails.
1085 Otto's too so-so to toss soot, too sot to toot SOSs. So?
1086 Our ancestors may have been ignorant, but they were not stupid.
1087 Our sponsor thought it was for ADA. In fact it was for C.
1088 Our vision will speed up time, eventually deleting it. -Alexander Schure
1089 Out of memory saving lines for undo - try using ed.
1090 Out of the mouths of babes comes semi-digested Pablum.
1091 Overall there is a smell of fried onions. (fnord)
1092 Pack my box with five dozen liquor jugs.
1093 Panem et circenses, that's what the public wants.
1094 Paranoia doesn't mean the whole world really isn't out to get you.
1095 Pardon me for breathing, which I never do anyway oh, God, I'm so depressed...
1096 Passing over a black hole temporarily disables ship.
1097 Password:
1098 People get it into their heads that this is a democracy. Well it isn't. -gwl
1099 People never go there anymore; it's too crowded. -Yogi Berra
1100 People really shouldn't spread gossip, but what else is it good for?
1101 People tend to congregate in the back of the church and the front of the bus.
1102 People usually do what other people have done before them.
1103 People who deal with bits should expect to get bitten. -Jon Bentley
1104 People who take cat naps don't usually sleep in a cat's cradle.
1105 People who think they know everything greatly annoy us who do.
1106 People will buy anything that's one to a customer.
1107 Per omnia saecula vombatidae.
1108 Perfect day for scrubbing the floor and other exciting things.
1109 Perfect love casteth out fear.
1110 Person who falls in blast furnace is certain to feel overwrought.
1111 Personality is a flimsy thing on which to build an art. -John Cage
1112 Philosophy is the Rule of Life.
1113 Philosopy: unintelligible answers to insoluble problems.
1114 Physician, bill thyself.
1115 Planning dooms most projects.
1116 Please log off, the computer is out to get in your room and drink?
1117 Please log off, the computer is out to lunch.
1118 Please take note:
1119 Please to remember the Fifth of November, Gunpowder Treason and Plot.
1120 Plunk your magic twanger, froggy.
1121 Pluralites non est punenda sine necessitate. -Wm. of Occam
1122 Plus ça change, plus c'est la même chose.
1123 Politicians, ugly buildings and whores all get respectable if they last long enough.
1124 Populus vult decipi.
1125 Pornography is in the groin of the beholder. -William F. Buckley
1126 Post hoc, ergo propter hoc.
1127 Post proelium, praemium.
1128 Pregnant ropuli.
1129 Premature optimization is the root of all evil. -D. E. Knuth
1130 Preserve wildlife -- pickle a squirrel today!
1131 Prevention makes the heart grow fonder.
1132 Primate behaviour only changes under the impact of new technology.
1133 Pro is to con as progress is to Congress.
1134 Procrastination is the art of keeping up with yesterday. -Don Marquis
1135 Programming and puddings demand consistency.
1136 Progress is made on alternate Fridays.
1137 Promptness is its own reward, if one lives by the clock instead of the sword.
1138 Proofreading is more effective after publication.
1139 Proper planning includes admitting that your plan may not work.
1140 Pulchritude possesses solely cutaneous profundity.
1141 Put not your trust in money, but your money in trust.
1142 Put your mouth where your mouth is.
1143 Quantity is no substitute for quality, but it's the only one we've got.
1144 Quantum mechanics do it with uncertainty.
1145 Questions are a burden for others; answers are a prison for oneself.
1146 Rain before sunset, dark by midnight.
1147 Rainy days and Mondays always get me down.
1148 Reach out and grep someone.
1149 Reading is thinking with someone else's head instead of one's own.
1150 Real programmers can't say `lint' without adding `hbaxcu' -Wm Leler
1151 Real programs don't eat cache.
1152 Reality is for those who can't handle drugs.
1153 Reality is good for you...in small doses.
1154 Reality is silly-putty. -Paul Krassner
1155 Reality seems harsher in the early morning.
1156 Reason establishes the foundation of faith. Faith compensates the error of reason.
1157 Reason is a universal instrument which can serve on any kind of occasion. -Descartes
1158 Reform always comes from below. No man with four aces asks for a new deal.
1159 Regnant populi.
1160 Rei panta.
1161 Religions revolve madly around sexual questions.
1162 Remember that "almost" means "not".
1163 Remember the Unknown Buffalo.
1164 Remember when you asked me to tell you when you were being inconsiderate?
1165 Remember why the good Lord made your eyes -- Pla-gi-a-rize! -Tom Lehrer
1166 Remember, UNIX spelled backwards is XINU.
1167 Remember, even if you win the rat race -- you're still a rat.
1168 Render unto Caesar if line 54 is larger than line 62.
1169 Repetition is a form of change. -B. Eno
1170 Research is a great career: you get paid for looking, regardless of results.
1171 Respect you in the morning?! Hell, I don't even respect you now.
1172 Restrain your octopus! The canoes are going fishing tomorrow.
1173 Ring around the collar.
1174 Ring the bell; close the book; quench the candle.
1175 Ritual is to the inner sciences what experiment is to the outer sciences. -Leary
1176 Rog-O-Matic callidus est.
1177 Rog-O-Matic perditus est.
1178 Rog-O-Matic's not expert enough. It could handle rogue, but it couldn't handle More.
1179 Rotten wood can not be carved -Confucius (Analects, Book 5, Ch. 9)
1180 Round numbers are always false. -Samuel Johnson (c. 1750)
1181 Rule 5 Violation
1182 SCCS: the source-code motel -- your code checks in but it never checks out. Ken Thompson
1183 SYS ERROR 0 - no error detected
1184 Sailors in ships, sail on! Even while we died, others rode out the storm.
1185 Satire does not look pretty upon a tombstone.
1186 Save a forest -- eat a beaver!
1187 Save the dot files!
1188 Save yourself! Reboot in 5 seconds!
1189 Say "no" to long-sleeved shirts!! Support your right to bare arms!
1190 Say your prayers, you're going to Zen heaven.
1191 Schroedinger might have been here.
1192 Schroedinger's cat is sitting on Heisenberg's shoulder and they are both laughing at you.
1193 Scintillate, scintillate, aster minific.
1194 Screw up your courage! You've screwed up everything else.
1195 Secrecy is the beginning of tyranny.
1196 Secret mail has arrived.
1197 See that ocean -- that used to be some ocean. -Burt Lancaster in Atlantic City
1198 Seek not to understand that you may believe, but believe that you may understand.
1199 Self denial is better than self degradation.
1200 Sell everything. Market top has been reached. -Joseph Granville
1201 Send not to ask for whom the bell tolls; it tolls for thee.
1202 Señor, if you hurry from here, you will wait longer there. -Mexico taxi driver
1203 Sex with someone you don't love is just gymnastics--and I hate exercise. -John Derek
1204 Shadows slick as eels slither through.
1205 Share your happiness with others today.
1206 She canna take much more o' this, Mr. Spock.
1207 Shift to the left! Shift to the right! Pop up! Push Down! Byte, byte, byte!
1208 Show respect for age. Drink good Scotch for a change.
1209 Si nummi immunis.
1210 Silver is pure. It's been a symbol of justice and purity since the year of the sun.
1211 Sin has many tools, but a lie is the handle which fits them all.
1212 Sink or Swim with Teddy!
1213 Sleep is an excellent way of listening to an opera.
1214 Smile ... tomorrow will be worse.
1215 Smoked carp is terrible unless you're out of smoked salmon.
1216 Smooth rotation butters no parsnips. -J. W. Tukey
1217 Snatch the pebble from my hand, Grasshopper.
1218 Snob intellectual bachelors can't have fun in San Antonio. -Ted Nelson
1219 Snoopy has fleas.
1220 Snow Day -- stay home.
1221 So long as radicals honor theory over facts, they will continue to dismantle their successes.
1222 So narrow minded is the boss that he has to stack his ideas vertically.
1223 Social innovations tend to the level of minimum tolerable well being.
1224 Soft soap often has a high percentage of lye in it. -- Salada Tea
1225 Solve et coagule.
1226 Some books are to be tasted, others to be swallowed. -- Francis Bacon
1227 Some day this war's gonna end.
1228 Some men are discovered; others are found out.
1229 Some of us feel that there is a loss of scholarship here, and we're not too happy about it. -Irvin Lustig
1230 Some scholars are like donkeys, they merely carry a lot of books.
1231 Some things are better left unsaid.
1232 Sometimes a cigar is just a cigar. -Sigmund Freud
1233 Sometimes it seems to me that men are children grown incompetent. -Carl Whitaker
1234 Sometimes you've gotta give it all you've got, because it just isn't enough.
1235 Soon you will be sitting on top of the world.
1236 Sooner or later everybody's gotta pay their tab.
1237 Sorting on the part of mendicants must be interdicted.
1238 Space travel is utter bilge. -Sir Richard Van Der Riet Wolley
1239 Spare no expense to save money on this one. -Samuel Goldwyn
1240 Speaking of poison, I'll see that you get some fresh breakfast immediately.
1241 Specialization is for insects. -Robt. A. Heinlein
1242 Spend extra time on hobby. Get plenty of rolling papers.
1243 Split a stick of wood, and the Christ is there, too.
1244 Spock: We suffered 23 casualties in that attack, Captain.
1245 Stack overflow in crawlout. User environment re-initialized. (FATAL$)
1246 Standing on head makes smile of frown, but rest of face also upside down.
1247 Status: R
1248 Stay away from flying saucers today.
1249 Stay away from hurricanes for a while.
1250 Stereotypes are one of the worst things in the world. -miteddie!nessus
1251 Sticks and stones may break my bones, but a laser beam is another matter.
1252 Stop searching forever. Happiness is just next to you.
1253 Stop searching forever. Happiness is unattainable.
1254 Stop searching. Happiness is right next to you.
1255 Stop worrying, you'll never get out of this world alive.
1256 Subject: Re: Re: Clar ... HUMBUG! - Wrongthink st - (nf)
1257 Succumb to natural tendencies. Be hateful and boring.
1258 Sum quod eris.
1259 Sun UNIX 4.2 Release 1.1 (IAS) #1: Tue Jan 29 01:25:15 PST 1985
1260 Sunday clears away the rust of the whole week. - Joseph Addison.
1261 Sure [Somoza]'s a son-of-a-bitch, but he's OUR son-of-a-bitch. -F.D. Roosevelt
1262 Surprise due today. Also the rent.
1263 Surprise your boss. Get to work on time.
1264 Surveillance should precede salientation.
1265 System down Tues. am for COBOL compiler installation.
1266 System going down at 1:45 this afternoon for disk crash.
1267 System going down for 5 minutes -- back up in barrels.
1268 System going down for 5 minutes -- back up in half an hour.
1269 System going down in 5 minutes.
1270 System might crash at any moment.
1271 System went down at Fri Dec 13 21:54:56 1901
1272 TERROR IN THE OUTPUT FILE A A
1273 TNT allows students the freedom to make mistakes.
1274 TSO -- it may be slow, but it's hard to use.
1275 Tai Chi is self-defense for people on Quaaludes.
1276 Take care of the luxuries and the necessities will take care of themselves.
1277 Take care of your peonies and the dahlias will take care of themselves.
1278 Te ayudare a recorder la cantidad a indoctos si releesme bien.
1279 Teach it ... phenomenology.
1280 Technological unemployment is total today -- 300 years ago we were all farmers.
1281 Tell the girls to slice the ham thin.
1282 Ten years of rejection slips is nature's way of telling you to stop writing.
1283 Terminals at home are always in the bedroom.
1284 Thank God I'm an atheist. -Aleister Crowley
1285 Thank you for choosing UNIX -- batteries not included, some assembly required.
1286 That goes against the laws of Physics.
1287 That must be wonderful! I don't understand it at all.
1288 That we can comprehend the little we know already is mindboggling in itself.
1289 That which does not kill me makes me stronger.
1290 That which does not kill me missed.
1291 That which is above is in that which is below.
1292 That's as American as pie charts.
1293 That's the nice thing about standards -- there's so many to choose from. -trb
1294 The $SIGNON command is a risky practice.
1295 The 3B2 Model 100 - the first machine with cat -v in ROM!
1296 The Angels want to wear my red shoes.
1297 The Beatles? Isn't that Paul McCartney's old band?
1298 The Blit is a nice terminal, but it runs emacs.
1299 The Constitution gives us freedom of religion, not freedom from religion -R Reagan
1300 The Emperor is not as forgiving as I am.
1301 The Force is strong with this one.
1302 The Force is with you, young Skywalker, but you are not a Jedi yet.
1303 The Government urges you to remain calm.
1304 The Inuit have dozens of words for snow, so why do the Dutch only have one word for rain?
1305 The Italians make money out of funding their own deficit.
1306 The Luddites always lose. Always.
1307 The Moral Majority are the people our ancestors came from Europe to escape.
1308 The PIXAR -- it's not just a job, it's an adventure.
1309 The SUN really is a hunk of junk. - Tom Duff
1310 The Tao which can be talked about is not the Tao. -Lao Tzu
1311 The Tree of Learning bears the noblest fruit, but noble fruit tastes bad.
1312 The UFO and the BVM seem to be the same phenomenon. -Jacques Vallee
1313 The UNIX system is harder to use than a toaster. -Kaare Christian
1314 The United States Army: 194 years of proud service, unhampered by progress.
1315 The aim of existence is to have clean ideas, change them like shirts.
1316 The aim of existence is to offer resistance to the flow of time.
1317 The answer you seek is in an envelope.
1318 The attacker must vanquish; the defender need only survive.
1319 The average legislator is somewhere nearly all the time. -Herb Nore
1320 The barge was in my blind spot. - Peter Hobson, Cambridge cox
1321 The best prophet of the future is the past.
1322 The better part of valour is discretion; in the which better part I have saved my life.
1323 The boundary condition of the universe is that it has no boundary. - S. Hawking
1324 The check is in the mail.
1325 The churches must learn humility as well as teach it.
1326 The common Welsh name Bzjxxllwcp is pronounced Jackson.
1327 The connotation depends on the beacon. - Mark V. Shaney
1328 The contrary of a compound is the aggregate of the contraries of the components. - De Morgan
1329 The contrary of an aggregate is the compound of the contraries of the aggregates. - De Morgan
1330 The coroner gave you a clean bill of health.
1331 The darkest hour is just before the storm.
1332 The dawning of the Information Age is bringing about dramatic changes in the fundamental fabric of our civilization. - AA Penzias
1333 The decision doesn't have to be logical, it was unanimous.
1334 The difference between a thief and the IRS is that the thief doesn't audit you afterwards.
1335 The difficult we gave up on yesterday, the impossible we are giving up on now.
1336 The early bird gets the coffee left over from the night before.
1337 The early worm gets the bird.
1338 The earth is like a tiny grain of sand, only much, much heavier.
1339 The empty fist always makes the deepest wound.
1340 The end is closer than you think.
1341 The end justifies the meanness.
1342 The enemy is ignorance [our own]. -Ezra Pound
1343 The eyes believe themselves, the ears believe other people.
1344 The fear of the lord was discovered before vitamins.
1345 The first piece of luggage out of the chute doesn't belong to anyone, ever.
1346 The first step in fixing something is getting it to break.
1347 The first thing we do, let's kill all the lawyers. - Henry VI, part II.
1348 The fit between the world and the human symbols describing it is never perfect.
1349 The following file systems are due for backup at this time:
1350 The fruits of impatience are bitter.
1351 The function of the sun is not to help the cabbages along. - Flaubert
1352 The further you get, the better it looks.
1353 The future isn't what it used to be. (It never was.)
1354 The future isn't what it used to be. -Arthur C. Clarke
1355 The gods do not protect fools. Fools are protected by more capable fools.
1356 The hardest job kids face today is learning good manners without seeing any.
1357 The hardest part of raising children is teaching them to ride bicycles.
1358 The hippo has no sting, but the wise man would rather be sat upon by the bee.
1359 The human brain is not a pretty sight.
1360 The human mind treats a new idea the way the body treats a strange protein - it rejects it. -Peter Medawar
1361 The invention of the multiple-choice exam was the death blow to competent writing.
1362 The judge's jokes are always funny.
1363 The ketchup of sorrow is better than the mustard of happiness.
1364 The last twenty-nine days of the month are the worst. -Nicola Tesla
1365 The lion will lie down with the lamb, but the lamb won't get much sleep.
1366 The love of money is the mucilage of many a tragic friendship -Stuart McMillan
1367 The man of knowledge can see several things at once.
1368 The map is not the territory. -A. E. Van Vogt, in World of Null-A
1369 The measure of the rigor of a science is the index of its ability to predict.
1370 The meek shall inherit the earth -- they are careful to hide the fact.
1371 The meek shall inherit the earth -- they are pronounced "o".
1372 The meek shall inherit the earth -- they are too weak to refuse.
1373 The more complicated the mind, the more simple the play.
1374 The more things change, the more they'll never be the same again.
1375 The more you run over a dead cat, the flatter it gets.
1376 The move of bambam functionality to the new AP bugs is re-scheduled to Friday night
1377 The nervous system sees no color, feels no pain. -T. Leary
1378 The null string has always been a locksmith. -Albert Einstein
1379 The null string has always been a productive source of off-by-0 errors.
1380 The number of UNIX installations has grown to 10, with more expected. - 2nd Edition UNIX manual
1381 The number of approved [COBOL] subsets has been reduced from 104,976 to 54. - JM Triance
1382 The official state animal of New York is the cabbie.
1383 The official state tree of North Dakota is the telephone pole?
1384 The one interesting fact about the Diplodocus is that the accent is on the second syllable.
1385 The only imperfect thing in nature is the human race.
1386 The only one who got everything done by Friday was Robinson Crusoe.
1387 The only people who listen to both sides of an argument are the neighbors.
1388 The only sure things in life are net.suicide and net.taxes.
1389 The only thing cheaper than hardware is talk.
1390 The only way out of a circle is through the center.
1391 The opera isn't over until the fat lady sings.
1392 The opposite of a trivial truth is false; the opposite of a great truth is also true.
1393 The pale companion is not for our pomp.
1394 The pearl the squirrel the girl hit bit split.
1395 The planes in Spain fall mainly in the rain.
1396 The play's the thing/Wherein I'll catch the conscience of the king.
1397 The plural of spouse is spice.
1398 The polhode rolls without slipping on the herpolhode lying in the invariable plane.
1399 The problem with a just economy is, who runs the Bureau of Economic Justice?
1400 The prudent man does not hold his breath.
1401 The reason Swedes put little o's over some A's is that ontology recapitulates philology.
1402 The reason Swedes put little o's over some A's is that they are pronounced "o".
1403 The religion that is afraid of science dishonors God and commits suicide.
1404 The rich man has his motor car, His country and his town estate. He smokes a fifty-cent cigar And jeers at Fate. - F. P. Adams
1405 The screen rectangle must be charged with emotion. Hitchcock
1406 The sheep - symbolic creature of docility, sacrifice and stupidity.
1407 The shorter the line, the slower it moves.
1408 The shortest distance between two points is off the wall.
1409 The shortest distance between two points is under construction. -Noelie Altito
1410 The skeletons in the cupboard will all come out in the wash.
1411 The solution to the problem of life is seen in the vanishing of the problem.
1412 The sooner you fall behind, the more time you have to catch up.
1413 The stapler runs out of staples only while you are trying to staple something.
1414 The sterile pleasure of being right tends to get stale in the course of a lifetime. EW Dijkstra
1415 The strength of a nation lies in the integrity of its homes. -Confucius
1416 The stylus is more potent than the claymore.
1417 The sword he sang a song of death/But could not make the sickle yield. -Blake
1418 The thing about Chinatown is, you can never be sure of anything down there.
1419 The three laws of physics: f=ma; things fall down; you can't push a rope.
1420 The tide of change approaches.
1421 The time is right to make new friends.
1422 The unexamined life is not worth examining.
1423 The universe is laughing behind your back.
1424 The vanity of teaching often tempteth a man to forget that he is a blockhead.
1425 The voice of the people is odd,/It is, and it is not, the voice of God. -Pope
1426 The wheels of justice grind slow but fine.
1427 The whole UNIX operating system was ripped off electronically.
1428 The whole UNIX operating system whose documentation fits in a chinese computer terminal!
1429 The wise shepherdess never trusts her flock to a smiling wolf.
1430 The world cannot be understood from a single point of view. -Eleanor Roosevelt
1431 The world ended yesterday-this is only a dream!
1432 The world ended yesterday-why are you still here?
1433 The world is a conspiracy of the unthinking against the unwitting.
1434 The world is all that is the case. -Wittgenstein
1435 The world is coming to an end! Repent and return those library books!
1436 Them that dishes it out need not fall over every time someone blows hard.
1437 There are more old drunkards than old doctors.
1438 There are more things in heaven and earth, Horatio,/Than are dreamt of in your philosophy.
1439 There are more ways of killing a cat than choking her with cream.
1440 There are no color bars in Cuba.
1441 There are only three kinds of proof: induction, exhaustion, and intimidation.
1442 There are two kinds of people in the world -- those who are, and those who aren't.
1443 There is a 10% penalty for getting yourself killed.
1444 There is a fly on your nose.
1445 There is a person with a shovel behind you ready to crack open your skull!
1446 There is a tide in the affairs of men/Which, taken at the flood, leads on to fortune. - Julius Caesar IV.iii.217
1447 There is a world in which this sentence ends with a different word.
1448 There is no bottom to worse.
1449 There is no fear in love; but perfect love casteth out fear.
1450 There is no gift like the present.
1451 There is no governor anywhere; you are absolutely free.
1452 There is no language in our lungs.
1453 There is no present like the TIMES.
1454 There is no present like time.
1455 There is no sin except stupidity. - Oscar Wilde
1456 There is no time like the pleasant.
1457 There is nothing more permanent than a temporary building.
1458 There is nothing more permanent than a temporary tax.
1459 There must be a minimum of two responsible people per subdomain. - Mark Horton
1460 There used to be men and women. Now there are men and persons.
1461 There was a phone call for you.
1462 There'll always be an England - if not it would be necessary to invent one.
1463 There's a broken light for every heart on Broadway.
1464 There's a difference between ethical people and nice people. You can't trust nice people.
1465 There's a divinity that shapes our ends,/Rough-hew them how we will.
1466 There's a sucker reborn every minute.
1467 There's always one more bug.
1468 There's got to be more to life than compile-and-go.
1469 There's insanity in my family; starting with me, tonight.
1470 There's no place like home.
1471 There's no room in the drug world for amateurs.
1472 There's something in this universe that I don't understand. -T. Duff
1473 These calculations even schoolchildren can master in three-four days. -Maimonides
1474 These numbers DO NOT appear to belong to anybody: 315 323 372 375 602 765 772 903 914
1475 These widows, sir, are the most perverse creatures in the world. - Joseph Addison.
1476 They couldn't hit an elephant at this dist... -- last words of Gen. John Sedgewick
1477 They laughed at Copernicus; they laughed at Galileo; they laughed at Bozo the Clown.
1478 They live happiest who have forgiven most.
1479 They were easy to tell apart: the good Kirk was played by William Shatner and the evil one by Gavin McLeod.
1480 They were easy to tell apart: the good Kirk wore cottons and wools and the evil Kirk wore nylons and polyesters.
1481 They're only trying to make me LOOK paranoid!
1482 Things always look darkest just before they go totally black. -Col. Hannibal Smith
1483 Things are more like they are now then they have ever been before. -Dwight D Eisenhower
1484 Things are more like they used to be than they are new.
1485 Things are more like they used to be than they are now.
1486 Things are only as bad as they are and can only get worse if they do!
1487 Things that go without saying go even better if they are said. -Talleyrand
1488 Things will be bright in P.M. A cop will shine a light in your face.
1489 Think of your family tonight. Try to crawl home after the computer crashes.
1490 This *means* something. -R. Neary
1491 This algorithm is prevented in the style of Dijkstra's guarded cowhands.
1492 This fortune intentionally not included.
1493 This fortune is inoperative. Please try another.
1494 This fortune is self-explanatory, once you understand it.
1495 This fortune left blank intentionally.
1496 This fortune was not meant for you.
1497 This is Emmanuel. I got him from Emmanuel Training School. He's Emmanuel like.
1498 This is a full standard Kernighan & Ritchie C compiler.
1499 This machine does not exist! Boy am I confused!
1500 This refutation can only be refuted by a proof. - van den Herik 1985
1501 This space available. Call 686-7600 for details.
1502 This statement is a lie.
1503 This system hasn't crashed in ages.
1504 This terminal is not for your use, please log off!
1505 This time for sure!
1506 This will be a memorable month -- no matter how hard you try to forget it.
1507 This will hurt me more than it hurts you.
1508 Thos who do not remember the past are condemned to repeat it.
1509 Those who can't write, write manuals.
1510 Those who can, do; those who can't, simulate.
1511 Those who can, do; those who can't, write.
1512 Those who can, do; those who can't, write. Those who can't write work for the Bell Labs Record.
1513 Those who do not remember the past are condemned to repeat it.
1514 Those who in quarrels interpose must often wipe a bloody nose.
1515 Those who talk don't know. Those who don't talk, know.
1516 Thrashing is just before they go totally black. -Col. Hannibal Smith
1517 Thrashing is just virtual crashing.
1518 Three shoes do not a hat make.
1519 Thunder is impressive, but it is lightning that does the work. -Mark Twain
1520 Time ends here, please go back the way you came.
1521 Time flies like an arrow but fruit flies like a banana.
1522 Time is nature's way of making more anarchy.
1523 Time is nature's way of making sure that everything doesn't happen at once.
1524 Time is three eyes and eight elbows.
1525 Timesharing just doesn't work. -K. Thompson, 1982.
1526 To be clear is professional; not to be clear is unprofessional. -- Sir Ernest Gowers
1527 To be is to be related.
1528 To be or not to be, those are the parameters.
1529 To criticize the incompetent is easy; it is more difficult to criticize the competent.
1530 To cross again is not to cross.
1531 To err is human, to forgive is not libary [sic] policy. quoted by Herb Caen
1532 To err is human, to really foul things up requires a computer!
1533 To err is human; that's why I'm comfortable around Gods.
1534 To express e, remember to memorize a sentence to simplify this.
1535 To iterate is human, to recurse, divine.
1536 To laugh at men of sense is the privilege of fools.
1537 To live without clocks is to live forever. -RLS
1538 To make an enemy, do someone a favor.
1539 To make an omelette, you have to paint it.
1540 To play billiards well is a sign of an ill-spent youth.
1541 To possess another language is to possess another soul. -Charles V
1542 Today is a good day to bribe a high-ranking public official.
1543 Today is the first day of the rest of your miserable life.
1544 Today is yesterday's tomorrow.
1545 Today the pits, tomorrow the wrinkles -- Sunsweet marches on.
1546 Together we must rise to higher and higher platitudes. -Richard Daley
1547 Together we will rule the galaxy, father and son. Luke...it is your destiny.
1548 Tonight's the night: Sleep in a eucalyptus tree.
1549 Too Much.
1550 Too much of a good thing is WONDERFUL. -Mae West
1551 Torque is cheap.
1552 Toto, I've a feeling we're not in Kansas any more.
1553 Toto, I've a feeling we're not in any immediate danger of having just committed suicide!
1554 Toutes choses sont dites deja, mais comme personne n'ecoute, il faut toujours recommencer.
1555 Transformation is invested with the mysterious and the painful.
1556 Travel important today; Internal Revenue men arrive tomorrow.
1557 Tres sabios hubo en el mundo, Adan, Solomom y Raymundo.
1558 Troglodytism does not necessarily imply a low cultural level.
1559 Troubles are like babies; they only grow by nursing.
1560 Trust Me.
1561 Trust him, but still keep your eyes open.
1562 Truth is only skin deep.
1563 Truth is the ultimate weapon; fortunately no one has perfected it yet. - Ken Ellis
1564 Truth will be out this morning. (Which may really mess things up.)
1565 Try `stty 0' -- it works much better.
1566 Try a new system or a different approach.
1567 Try again
1568 Try the Moo Shu Pork. It is especially good today.
1569 Try to divide your time evenly to keep others happy.
1570 Tu aideras a rappeler ta quantite a beaucoup de docteurs amis.
1571 Turning the other cheek merely ensures two bruised cheeks.
1572 Two fish in the sky are worth more than a bird in the sea.
1573 Two heads are better than a bath and a half.
1574 Two wrongs don't make a right. Two Wrights make airplanes.
1575 U.S. out of OAKLAND!
1576 UFO's are for real: the Air Force doesn't exist.
1577 UNIX acts as an equalizer of the hardware playing field. J. Scanlon
1578 Unbidden guests/Are often welcomest when they are gone.
1579 Uneasy lies the head that wears a crown.
1580 Unemployment is not a disease; so it has no `cure.'
1581 Unix is the only significant operating system whose documentation fits in a student's briefcase. -John Lions (Fixed in 4.1BSD)
1582 Unix never says `please.' -- Rob Pike
1583 Unix soit qui mal y pense.
1584 Unix: from now on, consider it dead. -Mike O'Dell
1585 Unknown Jerome's -- Dorothy's desk -- $.25 while they last!!
1586 Using 4.2 in this hospital is a great idea.
1587 Usura contra naturum est.
1588 Usus, Quen penes arbitrium est, et jus, et norma loquendi. -Horace
1589 VAX/VMS -- Software for the 60's.
1590 VAX/VMS is like a nightmare about RSX.
1591 Veni, vidi, maeni, mo, cacha tigrem baedas to, iffi hollers, ledem go, veni, vidi, maeni, mo.
1592 Versatility is one of your outstanding traits.
1593 Vests are to suits as seat-belts are to cars.
1594 Vigilia pretium libertatis.
1595 Violence is the last refuge of the incompetent. -Salvador Hardin
1596 Viva Nuestra Señora Guadalupe y jueron gubernacion mala. -Father Hidalgo
1597 Vivaldi did not write 600 concerti grossi. He wrote the same one 600 times. -Stravinski
1598 Vocatus atque non vocatus deus aderit.
1599 Vote anarchist.
1600 Vox populi, vox Dei. -Alcuin
1601 WAR IS PEACE. INFORMATION IS SLAVERY. OUR FUTURE IS IN OUR HANDS.
1602 Warning: I brake for no apparent reason.
1603 Warning: perch lorethylene may harm plastic
1604 Warning: this fortune may change your life.
1605 Wars do not log out!
1606 Waste not, get your budget cut next year.
1607 Wasting time is an important part of living.
1608 Watch out for quantum ducks: Quark! Quark!
1609 We aim to please, but our aim is bad.
1610 We are experiencing network trouble -- do not adjust your illegal descrambler.
1611 We are faced with an insurmountable opportunity. -W. Kelley
1612 We are not in any immediate danger of having solutions that exceed the needs.
1613 We can lick gravity, but sometimes the paperwork is overwhelming. -von Braun
1614 We continue to overlook the fact that work has become a leisure activity.
1615 We did it for nothing, we did it in an hour, and the whole thing worked.
1616 We don't care, we don't have to-- we used to be the phone company.
1617 We don't know half of what we know.
1618 We don't need a standard; Kernighan & Ritchie completely defines the language.
1619 We haul ours to kick theirs.
1620 We have a really challenging assignment for you.
1621 We have lost our little Hanner in a very painful manner. - Max Adeler.
1622 We have met the enemy, and he is us. -Walt Kelly
1623 We have the finest politicians money can buy.
1624 We learn from history that we do not learn anything from history.
1625 We must all hang together, or assuredly we shall all hang separately. -Franklin
1626 We never stand still longer than it takes to have an argument.
1627 We offer every assistance short of actual help.
1628 We place no reliance/on Virgin or pigeon;/Our method is science,/Our aim is religion. -Aleister Crowley
1629 We regard matrimony as a sort of friendship recognized by the police.
1630 We retard what we cannot repel, we palliate what we cannot cure. -Johnson
1631 We seem to be made to suffer. It's our lot in life.
1632 We shall never get people whose time is money to take much interest in atoms. -S. Butler
1633 We shall never understand one another until we reduce the language to seven words. -K. Gibran
1634 We should acknowledge the 10000-year sheep heritage of mankind. - Judge Clyde Burch.
1635 We try harder, they do better.
1636 We use it but we do not love it. -Goethe
1637 We want no foreign rulers - fight the metric system.
1638 We won't need reservations.
1639 We would like to apologize for the following announcement:
1640 We'll burn that bridge when we come to it...
1641 We're going up there this weekend and I'm gonna get so roaring, stinkin', no-good drunk I won't be able to see. - mechanic in "The Blob".
1642 We're scientists. We have to do things we hate -- that even sicken us.
1643 We're too close to System Test.
1644 We've lost 4 crays to the open environment.
1645 Welcome to the working week.
1646 Well, the handwriting is on the Titanic, why not go gentle into that good night?
1647 Well, the handwriting is on the floor. -Joe E. Lewis
1648 Well, we had Chinese food again for lunch.
1649 What I like about scientists is that they are a team, so that one need not know their names. -J Wilmot
1650 What I tell you three times is true. -The Hunting of the Snark.
1651 What did you throw that book I wanted to be read to out of about Down Under out for?
1652 What distinguishes good software from poor software is customer satisfaction. -Bob Yacobellis
1653 What do you call a half-dozen Indians with Asian flu? Six sick Sikhs (sic).
1654 What do you mean the 8080 & the 6502 are incompatible? They're both NMOS!
1655 What does it mean if there is no fortune for you?
1656 What garlic is to salad, insanity is to art.
1657 What good are the games if you ain't got the power?
1658 What good is someone who can walk on water if you can't follow in his footsteps?
1659 What have you done for Vic lately?
1660 What if I go to New York and can't trust a menu?
1661 What is mind? No matter. What is matter? Never mind. -Thomas Hewitt Key
1662 What is now proved was once only imagined. -William Blake
1663 What the hell, go ahead and put all your eggs in one basket.
1664 What this country needs is a good five-cent nickel.
1665 What use is magic if it can't save a unicorn? -Peter S. Beagle
1666 What's in a name? That which we call a rose/By any other name would smell as sweet.
1667 What's it all about? We're all tools. Life's just a crock.
1668 What's the point to combing your hair when it's grey and thinning?
1669 When all else fails, read the instructions.
1670 When all is said and done, a lot more is said than done.
1671 When an Okie moves to California, he raises the IQ of both states. -Will Rogers
1672 When an owl comes to a mouse picnic, it's not there for the sack races.
1673 When better machines are built, greg will break them.
1674 When better machines are built, jks will break them, and td will bitch about it.
1675 When bigger machines are built, scj will saturate them.
1676 When does later become never?
1677 When everyone's out to get you, paranoia is just good thinking.
1678 When faced with the obvious -- look elsewhere.
1679 When faced with two evils, one asks why only two?
1680 When four sit to conspire, three are government agents, and the other a fool.
1681 When in doubt, lead trump.
1682 When in trouble or in doubt, run in circles; scream and shout.
1683 When marriage is outlawed, only outlaws will have inlaws.
1684 When more and more people are out of work unemployment will result. -Calvin Coolidge.
1685 When the Lord gets ready, you got to move.
1686 When the going gets tough, the tough go shopping.
1687 When the going gets tough, the tough hold meetings.
1688 When the map and the terrain disagree, trust the terrain. -Swiss army aphorism
1689 When the wind is great, bow before it; when the wind is heavy, yield to it.
1690 When time permits, your personal life will be exciting.
1691 When traveling with a herd of elephants, don't be first to lie down and rest.
1692 When you are over the hill, you pick up speed.
1693 When you need a sledgehammer, the finest scalpel just won't do.
1694 When you're damned if you do and damned if you don't, then DO!
1695 Whenever I see his fingernails, I thank God I don't have to look at his feet.
1696 Whenever I'm caught between two evils, I take the one I haven't tried before. -Mae West
1697 Whenever the Queen comes to New Zealand the Maori people suffer a disaster.
1698 Where do you think you are, Civilization?
1699 Whereof one cannot speak, thereof one must be silent. -Wittgenstein
1700 While I see many hoof-marks going in, I see none coming out. - Aesop.
1701 Who can worry about a super-hero who vanishes when you change channels?
1702 Who is W. O. Baker, and why is he saying those terrible things about me?
1703 Who is the slayer, who the slain? Speak... -Sophocles, Oedipus Rex
1704 Who knows if there are any answers? -Edmund G. Brown, Jr.
1705 Who needs companionship when you can sit alone in your room and drink?
1706 Who ordered that? -I.I. Rabi on the discovery of the muon
1707 Who's afraid of Louisa May Alcott?
1708 Whom the gods must destroy they first must drive insane.
1709 Why be a second rate Ravel when you can be a first rate Gershwin?
1710 Why do they have this marked "Danger, do not touch"?
1711 Why do we have two eyes? To watch 3D movies with.
1712 Why don't we store the blank punch cards on disk, and get rid of all those boxes.
1713 Why is it called a stream I/O system when the data flows both ways?
1714 Why polish the corners off a sphere in a roomful of cubes?
1715 Why worry about tomorrow, when today is so far off?
1716 Will nobody help the widow's son?
1717 With clothes the new are best, with friends the old are best.
1718 With redeeming social value like yours, no wonder you're obscene.
1719 With the wind in the east I can tell an eagle from a hammer.
1720 With/Without -- and who denies it's what the fighting's all about?
1721 Without alkaloids, life itself would be impossible.
1722 Wombat omnia vincet.
1723 Wombs not bombs
1724 Women seldom show dimples to guys who have pimples.
1725 Wonderful girl! Either I'm going to kill her or I'm beginning to like her.
1726 Words are the voice of the heart.
1727 Words must be weighed, not counted.
1728 Work expands to fill the time available for its completion. -C.N. Parkinson
1729 Worth seeing? Yes, but not worth going to see.
1730 Writing free verse is like playing tennis with the net down.
1731 Y drag goch yr y gchwyn!
1732 Yamata wasami shuza.
1733 Yea, from the table of my memory/I'll wipe away all trivial fond records.
1734 Yes, the red switch.
1735 Yesterday's sensation is today's calibration and tomorrow's background. -Valentine Telegdi
1736 Yogsothoth Neblod Zin.
1737 You always think you know what you're doing, but you're too slick for your own good.
1738 You are going to have a new love affair.
1739 You are in a maze of twisty little passages, all alike.
1740 You are original and creative.
1741 You attempt things that you do not even plan because of your extreme stupidity.
1742 You auto buy now.
1743 You can create your own opportunities this week. Blackmail a senior executive.
1744 You can get HELP any time you are using TEACH by returning to the command state and typing "S 160".
1745 You can lead a horticulture but you cannot make her think. - Dorothy Parker
1746 You can observe a lot just by watching. -Yogi Berra
1747 You can tell a man by the company that keeps him.
1748 You can't beat the bugs.
1749 You can't build a bomb at 300 baud.
1750 You can't capitalize your cake and expense it too.
1751 You can't comb a hairy ball smooth.
1752 You can't fall off the floor.
1753 You can't forward backward. - Dave Nowitz
1754 You can't go home again, unless you set $HOME
1755 You can't have everything -- where would you put it?
1756 You can't miss it.
1757 You can't teach a dead dog new tricks.
1758 You can't win, you can't break even, and you can't get out of the game.
1759 You can't win. But there are alternatives to fighting.
1760 You cannot buy beer; you can only rent it.
1761 You cannot count friends that are all packed up in barrels.
1762 You cannot cross a chasm in two steps.
1763 You cannot kill time without injuring eternity.
1764 You cook it, you sell it.
1765 You dialed 5483
1766 You display the wonderful traits of charm and courtesy.
1767 You don't have to play tennis any more, or talk to anyone who does.
1768 You don't really want to know what the future holds for you.
1769 You had mail.
1770 You have an ambitious nature and may make a name for yourself.
1771 You have been selected for a secret mission.
1772 You have been transfixed by the gaze of the Edlund.--More--
1773 You have bills.
1774 You have had a long-term stimulation relative to business.
1775 You have made an excellent hit on the UNIX.--More--
1776 You have mail.
1777 You have personal talents that are attractive to others. Be sure to use them.
1778 You have plate mail.
1779 You have slowmail.
1780 You have snails.
1781 You have splint mail.
1782 You have taken yourself too seriously.
1783 You have the capacity to learn from mistakes. You'll learn a lot today.
1784 You know, Louis, I think this is the beginning of a beautiful friendship.
1785 You know, you never know.
1786 You look strong enough to pull the ears off a Gundark!
1787 You make the megabucks, I make the nanobucks...it's YOUR problem.
1788 You may be recognized soon. Hide.
1789 You may enjoy the infamous PEOPLExpress snack pack for one dollar.
1790 You may have a friend at the Chase Manhattan but at our bank you have meshpocheh!
1791 You might have mail.
1792 You need not worry about your future - it's going to be rotten.
1793 You never know what you don't know, you know?
1794 You now have Asian Flu.
1795 You press the button, and we'll do the rest.
1796 You remind me of a TV show, but that's all right: I watch it anyway.
1797 You scream and you leap.
1798 You seek to shield those you love and you like the role of the provider.
1799 You should go home.
1800 You tend to be shy when undressing outdoors.
1801 You want it bad, you'll get it bad.
1802 You weren't here so we did it anyway.
1803 You will attend a party where strange customs prevail.
1804 You will be Told about it Tomorrow. Go Home and Prepare Thyself.
1805 You will be a winner today. Pick a fight with a four-year-old.
1806 You will be surprised by a loud noise.
1807 You will feel hungry again in another hour.
1808 You will get a better gorilla effect if you use as big a piece of paper as possible.
1809 You will make a small sum by investing in a business project.
1810 You will make a small sum disappear by investing in a business project.
1811 You will make many changes before settling satisfactorily.
1812 You will never find a more wretched hive of scum and villainy.
1813 You will step on the night soil of many countries.
1814 You win some, you lose some, and some go into extra innings.
1815 You worry too much about your job. Stop it. You are not paid enough to worry.
1816 You'll just have to sleep faster tonight.
1817 You're being followed. Cut out the hanky-panky for a few days.
1818 You're so bossy you ought to be milked before you come home at night.
1819 You're so ugly you couldn't even get a better mouse.
1820 You're so ugly you couldn't even get a date with an automated bank teller.
1821 You've always got the option of having just committed suicide!
1822 You've been leading a dog's life. Stay off the furniture.
1823 Your First Amendment ends where the next person's Bill of Rights begins. P. Michael Guba
1824 Your best dreams may not come true; but then neither will your worst dreams.
1825 Your computer account is overdrawn. Please reauthorize.
1826 Your editor doesn't always know best.
1827 Your emotional nature is strong and sensitive
1828 Your empty file directory has been deleted.
1829 Your intuition is excellent but another viewpoint could be helpful.
1830 Your login has been changed.
1831 Your love life will be happy and harmonious.
1832 Your mind understands what you have been taught; your heart, what is true.
1833 Your opponent wouldn't fight if he didn't think he had a chance.
1834 Your password is pitifully obvious.
1835 Your present plans are going to succeed.
1836 Your supervisor is thinking about you.
1837 Your theory is crazy, but not crazy enough to be true.
1838 Zero is greater than minus zero, but don't ask by how much. -6600 ref. manual
1839 `By the way, microcode is no big deal. You can emulate it in random logic.'
1840 `Compared to academic politics, political politics is a nice, clean game.' -S. I. Hayakawa, SF Examiner 4/23/84
1841 `Drawing on my fine command of language, I said nothing.'
1842 `He was so narrow minded he could see through a keyhole with both eyes...'
1843 `I saw it with my own eyes' means you wanted to see it.
1844 `Otto' spelled inside out is `toot.'
1845 `Qvid me anxivs svm?'
1846 `She read her boyfriend's mind, and they're no longer going together,' Mrs. Resch added.
1847 `The time (6:39 pm) has come,' the Walrus said, `to talk of many things...'
1848 `The time has come,' the Walrus said, `to talk of many things...'
1849 `We don't care. We don't have to. We're the Phone Company.'
1850 ``I'm a hugger, I'm a tactile politician,'' Turner said.
1851 `is false when preceded by its quotation' is false when preceded by its quotation.
1852 `is not a sentence' is not a sentence.
1853 awk: Usage: awk [-f source | 'cmds'] [files]; record number 3.55646e-311
1854 awk: illegal statement 206620
1855 bad input char: .Ppm{=P!*@)Z9oFPp|*?)Z9pv9i%Su$^J)48%K_e239GM#ffoq!!!"!Mp#V6N\H8uEgdXbP\[7j1&PJz!X76!4BA}5!!!!!"syui!!!"!Mp#V6P\Scb?p8`;!4lf&
1856 beware of component 3730
1857 cc: warning: -g disables -O
1858 chess tonight
1859 dis: invalid general addressing mode (e8); notify disassembler implementor
1860 f u cn rd ths u cn gt a gd jb n cmptr pgmng.
1861 f u cn rd ths u cn gt a gd jb n tk wr
1862 f u cn rd ths, itn tyg h myxbl cd.
1863 fortune: Command not found.
1864 fortune: not found
1865 ftp> Globbing off.
1866 ftp> Globbing on.
1867 grep: RE error 41: No remembered search string.
1868 gt: warning -- bad idea to override alpha computation on matted-to-black target
1869 He who lives by the nit dies by the pick.
1870 invalid control line !!!
1871 itiprobe says hi
1872 jim is a nice editor except that it runs on the Blit. -- W. Joy
1873 no shell.
1874 non-positive output count: .!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1875 not not not Algol
1876 panic: trap
1877 pic: 5 X 58008 picture shrunk to 0.000603365 X 7
1878 pm monday am
1879 reading symbols...done
1880 size: a.out: bad magic
1881 startup: system error -- directory deleted
1882 struct sleaziness { char *pleasure; int alchemically; };
1883 too much.
1884 ucode rev x62
1885 unknown troff command: We will interpret typing statements A@imp#M:@gr(s)#
1886 unseal: invalid length
1887 usend: /usr/asp/spool filesystem is exhausted
1888 uucp failed completely (11)
1889 uucp failed partially: 0 file(s) sent; 1 error(s)
1890 uuxqt cmd (rnews ) status (ucsfcgl!uucp 256)
1891 values of β will give rise to dom!
1892 warning: vector size unknown: p[i][j] means *(*(p+i)+j)
1893 There's no backspace in real life. - P.J.Weinberger
1894 When a musk ox goes faster than an amble, he has formed an intention.
1895 Verb is a noun.
1896 Verb is not a verb.
1897 Verb is not a verb, unless it's verbed.
1898 Version 8 Unix style Ritchie streams.
1899 Space shuttle experience is more common than C++
1900 CA002 - [CAL] ASSEMBLY TIME: 0.000000 CPU SECONDS
1901 Within her left armpit only the fish called raawaru are there.
1902 In her right armpit, snapper only are the fish of that place.
1903 In days of yore, the crab and the crayfish lived in the forest.
1904 "C" is as portable as Stonehedge!!
1905 Any mail routed through "emacs" will probably fail without benefit of a bounce-back.
1906 Although the moon is only 1/100 the size of the earth, it is much further away.
1907 Never walk across a river that has an average depth of four feet.
1908 chdir: ?I/O error: `I/O error'
1909 ON SATURDAY SUPERMAN WILL BE UNAVAILABLE FOR A MAJOR HARDWARE RECONFIGURATION
1910 03:23:33 0.0017 USER CLOSE CALLS - 8
1911 It's clear that buzzwording is a factor.
1912 Dallas stands for culture with a 'K'.
1913 Huge directory ./src/port --call administrator
1914 CC119 - Dead code generated for vacuous expr.
1915 Resent-Comment: It's not OUR mailer. Maybe it's yours.
1916 * Method As described above, see details below.
1917 Take your hands off me.
1918 You don't have to give me all the gory details about how you got hepatitis.
1919 Who's the big cheese around here?
1920 What a surprise to find you here alone!
1921 Ouch! That feels good!
1922 How exciting to see you in traction again!
1923 Either I've been missing something, or nothing has been going on.
1924 You crossed my mind, but you didn't stay there.
1925 Should you die, I'd go mad so I could talk to you all the time.
1926 If you'll take me where I want to go, I'll take you where you think we are.
1927 If snow is wet, what is light?
1928 If your intentions are really good, I'll never understand them.
1929 Whatever happens, happens because it must.
1930 Get out, and take your mucus with you.
1931 I wanna lick the syrup off your hotcakes.
1932 I've got you under my skin; moreover, you've invaded my lymph.
1933 All I do is wait for your clumsy hands to make mincemeat of my apparel.
1934 More than just a book -- it's a major piece of torture.
1935 Great men are not always idiots.
1936 Unrequited love's a bore. -- Billie Holiday
1937 I wish people wouldn't say "Excuse me" when I WANT them to step on my feet.
1938 Life is a stage attacked by an idiot.
1939 No one wants to get into his grave still feeling frisky. -- Quentin Crisp
1940 (warning) data origin prohibits saving reloc bits
1941 ## wc is a Berkeley-ism, I think.
1942 Boost, don't knock
1943 NEW fsname = x, NEW volname = 49a126 -- DEL if wrong!!
1944 New Jersey has more people per capita than any other state.- Alan Karcher, D, NJ
1945 Significantly improved programming is only a reply card away.
1946 An AI journal without hype? That's like a hot air balloon without the hot air.
1947 UNIX is a trademark of AT&T in the U.S.A. and other countries.
1948 554 Who are you?
1949 Anything is possible, and it usually does. - John Lions
1950 When you become a streetwalker, you don't write home very much.
1951 Few forgive without a fuss.
1952 Your contraption is better than mine.
1953 Very well, I'll slick your hair down myself.
1954 If Lucifer confesses, we'll let the rest of you go.
1955 pass 2 error:(file ) more than 100 args?
1956 in read: Error 0
1957 There's a time and a place for spontaneity.
1958 I am a little more weird today than normal. - Andrew Hume
1959 You will be fortunate in everything you put your hands to.
1960 If nothing is pressing, putter around at this or that.
1961 Whatever arrangements you make are apt to be final.
1962 If you have a procedure with 10 parameters, you probably missed some.
1963 There's going to be no serious problem after this. - Ken Thompson
1964 If you can stick your finger in it, you can hang from it. -Andrew Hume
1965 Life's a bitch and then your feet wear down. - Dennis Ritchie
1966 Thank you for using AT&T!
1967 Small earthquake in Chile. Not many dead.
1968 Nepal premier won't resign.
1969 Surprises unlikely in Indiana.
1970 University of Rochester decides to keep name.
1971 In the long run, we are all dead. -Keynes
1972 Debate goes on over the nature of reality.
1973 Reach out and Boyer-Moore egrep someone.
1974 The solution is to increase the size of the manuals. - Mark V. Shaney
1975 `C' is for `core dumped.'
1976 redefinition: GLOBL 153352(gok(-118))[A7*16],gok(-116)/-937488177[R0*0]
1977 The electron: May it never be of use to anybody. - toast at the Cavendish Labs.
1978 Delivered-Automatically-By: the Magical Vacatioin Program
1979 Wretches, utter wretches, keep your hands from beans!
1980 Abstain wholly from laurel leaves.
1981 init: /dev/console: getty failing, sleeping
1982 25% of all books from Bell Labs are written by Narain Gehani.
1983 Try to clear up differences with associates
1984 * W * :test$cstatic$chatypedef$st$int$$cnt$$unsigned$$unsigned$$char$$fla$char$$fil$$FILEo: 1: CC019 - Old-fashioned Initialization. Use '=' Instead.
1985 The atom of hydrogen contains about a thousand electrons. - J.J. Thomson, 1903
1986 The unique power of UNIX (UPOU) is that vi includes awk.
1987 Yes, I want a drink. Alcoholic, of course; after the heavy sessions regarding quantum mechanics.
1988 * W * :../os/main.c: 64: CC042 - Instruction Will Cause Infinite Loop
1989 But issues remain in the AT&T Information Systems unit.
1990 The major problem is with sendmail. -Mark Horton
1991 Michigan House Fails to Override Veto of Medicaid Abortion Ban.
1992 The -v option increases user-friendliness.
1993 Every good joke has a short punch line.
1994 What is the origin of the Grand Canyon? A Scotsman lost a nickel.
1995 Sentence without verb.
1996 mh/toy/forbes deferred for sequence
1997 "":5:operands of ++ have incompatible types
1998 How do you explain that you changed your mind when you changed your hat? -Wm. Rogers
1999 The Devil Still Exists, Says Pope, Contradicting Polls
2000 When andrew asks you to type pwd for him, don't do it.
2001 Variable syntax.
2002 WARNING: You may see display garbage as a result of this action.
2003 WYSIWYG processing and a "vi"-like user interface - the best of both worlds! :-)
2004 strip: arno: bad magic
2005 There appears to be a paper jam, dammit p&P6.
2006 As Maine goes, so goes Vermont. -Alf Landon
2007 If you enter a village where everyone is lame, eventually you will start to limp.
2008 That's the way I got promoted, by eating everything. -pjw
2009 charge.c: 163: CC001 - Internal Compiler Error 69 . Debug: (412127)request for s1 but pseudo already in s3
2010 In 1974 it was hard to find anyone who voted for Richard Nixon in 1972.
2011 Charlie don't hack.
2012 A strange event will change your idea of a good time.
2013 I just resent the newgroup messages. -Rick Adams
2014 I'm not easily impressed on Mondays. -Bruce Ellis
2015 Mirrors should reflect a little before throwing back images. -Jean Cocteau
2016 What he's asking you to do is only mildly disgusting -- try it, you might like it.
2017 The 1980's have quite appropriately been called the age of nail extension products.
2018 Wonder woman will be down Saturday, November 15th for hardware maintenance.
2019 Arbitrary makes free.
2020 Don't puting nathing in the line. Today is washing poison machine.
2021 Pittsburgh has become a kind of knowledge aircraft carrier, its "top-guns" scattered regularly around the planet.
2022 The only works of art America has given are her plumbing and her bridges. -Duchamp
2023 Per dollar, the cray is cheaper to maintain than the comets. -pjw
2024 The entire LC comp center will be shut down from 12/12 to 12/15 for annual maintenance on our Uninterruptable Power Supply.
2025 Hit the water! Hit the water!
2026 Try psychoacoustic imagery risk free!
2027 Hit me with your mid-point, she said meanly.
2028 The secretaries don't understand me. -Rob Pike
2029 I have a brain. -Kerry Harrigan
2030 System won't be available tomorrow 12/04 from 18:00 to 20:00 to install new cross compiler.
2031 Some logins deserve a message. Some don't. Yours does. Here's mine.
2032 God has spoken to me through chocolate fudge cake.
2033 Some day, when the universe has its heat death, they will look back and say `There are 12 Cray-2s'. -pjw
2034 When the music stops, the house of cards collapses and the emperor is found to be wearing no clothes.
2035 pwedit: error in input file in item 2305843009213693953 at field 1
2036 Decreased cabin volume was insufficient to support human life.
2037 When ideas fail, words come in very handy. -Goethe
2038 elongated pentagonal gyrocupolarotunda (J41): 21/36 ambiguous hinges
2039 Total performance commercial carpet in convenient 18" squares
2040 A procedure can never use its own name in any way except to refer to itself.
2041 I'm a GEI kind of guy. - J Bentley
2042 eqn: illegal size of ignored near line 386, file part.5
2043 Music is the can opener of the soul. -Henry Miller
2044 Robert Elz is the Mark Horton of the south. - P. Dick-Lauder
2045 2 -rw-r--r-- 1 mp 1239 Jan 17 09:40 hite upper middle class IS AN INVALID DESTINATION.
2046 Rest frequently while shoveling snow.
2047 Never put snow on a frostbitten part.
2048 Eat more fish and less red meat.
2049 Drive away from a tornado at a right angle.
2050 Start off the day with a nourishing meal.
2051 Keep stairways clear of clutter.
2052 Discard medicine more than two years old.
2053 Stopping smoking slows emphysema's progress.
2054 Reduce speed in wet or foggy weather.
2055 Lengthen interval when the road is wet.
2056 Before physical activity warm up gradually.
2057 Don't eat a large meal before driving.
2058 Get help when lifting heavy objects.
2059 Don't use gasoline for cleaning.
2060 Put a smoke detector in your vacation cottage.
2061 Always read the labels on pesticides.
2062 To avoid falls watch where you step.
2063 To overcome stress do things that relax you.
2064 Popcorn is a good fiber food.
2065 Gray-tinted sunglasses reduce glare the most.
2066 Cut down on fatty, high-calorie foods.
2067 Use a salt substitute if blood pressure's high.
2068 Replace worn electrical cord without delay.
2069 Good passing rule: when in doubt, don't.
2070 Bicycle with the traffic flow.
2071 For relief submerge a bum in cold water.
2072 Always check fire exits in hotels and motels.
2073 Draw up a family fire-escape plan.
2074 Go with your kids when you go trick or treating.
2075 Take your car in for a tune-up.
2076 Carry a medical information card.
2077 Keep flammables away from space heaters.
2078 Buckle up even on short auto trips.
2079 Drive with the traffic not against the clock.
2080 Send your party guests home sober.
2081 Let me put it to you this way: computers are my business. - A.G. Hume
2082 Business is where the money is. - John Scully (CEO of Apple)
2083 Anything with the word 'generation' in it has to be wrong. - T.A. Cargill
2084 Today's technological mastery is tomorrow's obsolescence.
2085 23582.0u 2166.7s 21404r mk
2086 A mathematician is a machine for turning coffee into theorems. -Paul Erdös
2087 SCAPEGOAT=rob
2088 sh: /dev/null restricted
2089 Do not smoke near an open drawer. - Bell Labs safety manual.
2090 Like Nero, the government fiddled while Rome burned--only it wasn't Rome. -- Jim Olson
2091 FYI: POWER DIP OCCURED YESTERDAY AT 21:55...IS YOUR 3B2 OK???
2092 Don't ignore where the writer is in the draft.
2093 Hunting & Fishing licenses are free to the blind, handicapped or mentally retarded.
2094 mail: new message arrived
2095 Bad termcap entry
2096 Reverting to old tty driver...
2097 Thank you for using AT&T.
2098 The preferred steel for rodent protection is Type 304 stainless with a thickness of 3 mils.
2099 I'm TRYING to be a back end! - A Hume
2100 Stay clear of falling objects.
2101 5/26: /unix2 out of pace please clean up!!!!!
2102 Redundant hardware is not cost-effective when compared to administration-mediation solutions.
2103 Warning: .lastlogin was altered since last login
2104 If it's Weinberger, I'm going with Ditzel. - rob
2105 If you have any questions, call Ralph Knag at MH x5291
2106 Possession is nine-tenths of the privileged computer access code of ethics.
2107 Ignorance of the privileged computer access code of ethics is no excuse.
2108 It's not easy being Joan. -- rob
2109 Omit needless words that cause verbosity.
2110 rx: call to gauss failed: who_cares
2111 chown to owner: Not owner
2112 There are only 26 calls and most of them are trivial.
2113 In this country, everything loose rolls to the west coast. -T. Vanderslice, Apollo
2114 We have people doing a lot of fun stuff. That doesn't mean you don't wear suits. -R. Pampel, Apollo
2115 ROOT MODIFIED
2116 I don't have any courses for which I haven't written books. -Andy Tanenbaum
2117 Stop.
2118 (a0719) u wPM-US-Add a0712-a07rethan80mph.Thearrestingpatrolmanaskedhimifwantedtochecktheinstrumentusedtorecordhishighspeed. 07-21 0794
2119 550 ians... User unknown: Not a typewriter
2120 DELTA backup is running, system response will be slightly degraded.
2121 tar: slg/duckstuff/desktop/UNIXpractice.drw/shortcuts.fdr/spaces?slashes.fdr/.@questions and comments.doc: file name too long
2122 The world should be full of Brian Kernighans and technical people. -J Macor
2123 If you keep an open mind, people will put a lot of garbage in it.
2124 A monoid is an associative monad; its underlying magma is a semigroup.
2125 162 is unimplemented
2126 Norm does not protect against overflow. - cos(9.3)
2127 Content-Length: 0
2128 In our system, /usr/include/sys is a hazard. -mvs
2129 Awk is certainly not perfect. - The Awk Book
2130 Areas of communication may be very busy at present.
2131 Gratuitously incomplete sentence.
2132 xyv: protocol fault for some string
2133 You are the sponsor for the account andrew (Andrew Hume).
2134 I am not worried about the real world. -Pamela Zave
2135 To 8 AM EDT /79: high 63 low 5, prob. precip. to 8 PM 0% to 8 AM 2147477332%
2136 Digital plans to offer a better solution, not a better product. - R. Glorioso, DEC
2137 I've got it! It's a triple helix! L. Pauling 1954.
2138 Incest more common than thought in United States
2139 RFC 822 delenda est.
2140 I'm not writing any more tapes, ever. -A. Hume.
2141 Subject: Please ignore extra headers
2142 I wouldn't take any advice, if I were you.
2143 The blue drinks are $5.75, the pink $8.00.
2144 You are unlucky enough to bump into all my rough edges. -A. Hume
2145 When you're getting fired at from both sides, you're in the middle of something.
2146 A vertical conference is a center-wide conference. - Steve Bellovin
2147 It is Unix. It is possible to overcome any number of these bogus features. -pjw
2148 "term/select.c", line 116: compiler error: bad bigsize: 010
2149 Sorry, I don't know how to deal with your 'dumb' terminal.
2150 I am become death, the shatterer of worlds. -Baghavad Gita (quoted by Oppenheimer)
2151 The product classroom is marked pass-fail.
2152 An X server itself is not a big piece of software, only a few 100K.
2153 So, the next time something doesn't work, just push 'til it clicks. -Ag Primatic
2154 I have a different view of the world. -Andrew Hume. Show&Tell '87
2155 For 40 days and 40 nights, you [Arthur Fadden] held the destiny of Australia in the hollow of your head. -Arthur Calwell
2156 The best weapon against breast cancer is early detention.
2157 Licorice is the liver of candy. -Michael O'Donoghue
2158 Al Schumann, that devil-may-care Intern from FSD is leaving Tom Houghton's Security Group.
2159 Confession is good for the soul only in the sense that a tweed coat is good for dandruff. -Eisenhower
2160 Is there no room for competition in the standards industry? -R. Hardin
2161 Now is not the time to be falling out of windows. -R Mclellan
2162 A universal thought dispenses with communication.
2163 ISDN is real and implementable.
2164 When a man celebrates his God, he changes his sex.
2165 The rays of the Sun are penholders which night gorges with ink. -- Reb Adal
2166 Warning: system out of share structures, using "root".
2167 Wed Dec 30 21:27:30 1987 EDT
2168 5. Il riversamento = dump in inglese.
2169 E tutta colpa di Ken!
2170 Ken is an allem schuld!
2171 C'est la faute de Ken!
2172 Het is de schuld van Ken.
2173 I've got lots of bad examples. -td
2174 (void)vacuous(node);
2175 I'd rather have :rofix than const. -DM Ritchie
2176 To dissimulate is to feign not to have what one has. - J Baudrillard
2177 unlinking v/v1971/272; already have /n/bowell/usr/games
2178 FAILING HW: DEC
2179 Life is what the least of us make most of us feel the least of us make the most of. -Quine
2180 Received: from Messages.6.0.CUILIB.3.41.SNAP.NOT.LINKED.holmes.andrew.cmu.edu.rt.r3 via MS.4.0.holmes.andrew.cmu.edu.rt_r3
2181 The better your 4-wheel drive, the further out you get stuck.
2182 With Basic you just use a GOTO, with Pascal you have to indent 99% of the program halfway across the page! -Ted M. Young (A Basic programmer for 12 years)
2183 You know your apartment's small if you can't tell its position and speed simultaneously.
2184 ... Forking an allegro process requires only seconds... -V. Kelly
2185 Rainbows are just to look at, not to really understand.
2186 Some day we may discover how to make magnets that can point in any direction.
2187 One hundred humidities equal one rain.
2188 Genetics explain why you look like your father and if you don't why you should.
2189 Vacuums are nothings. We only mention them to let them know we know they're there.
2190 Thunder is a rich source of loudness.
2191 But an autopsy on the woman's headless body failed to reveal why she died.
2192 For ease of arithmetic we call 256 the largest index even though it is really 255, except at 255 itself. -- from a manual
2193 Only the future is certain; the past is always changing. -Polish proverb
2194 A victory is the greatest tragedy in the world, except a defeat. -Wellington
2195 A victory is the greatest tragedy in the world, except SunWindows. -Wellington
2196 If you don't have a sense of humor, it's just not funny. -Wavy Gravy
2197 Noalias must go. This is non-negotiable. -Dennis Ritchie
2198 We are currently experiencing all printing problems
2199 Due to illness, the /tbl design review is postponed until further notice.
2200 Due to technical problems, the BEST movie will be shown tommorrow.
2201 We say space is 3 dimensional because prison walls are 2 dimensional. -Hermann Weyl
2202 Two wrongs don't make a right; three lefts do.
2203 I've got plenty of inputs and outputs. I don't need the video. -Andrew Hume
2204 Cannot open phone book for <attrd>. Try a different company.
2205 con: connecting to coma
2206 We may be bureaucrats but we are not venal. -IRS Chief Counsel William Nelson
2207 Children can be substituted for adults in any case; however adults cannot be substituted for children. -Amtrak
2208 Education is basically useless, except for those rare cases when it's not really necessary. -Feynman
2209 Your 1 requests have been sent
2210 The book every man has inside him should usually stay there. - AJP Taylor
2211 X windows uses its hindbrain instead of its forebrain. -N Wilson
2212 Cryptogamous concretion never grows on mineral fragments that decline repose.
2213 The best place to find new dinosaurs is to look in basements. -Robert T. Bakker
2214 DUE TO DAMAGES, ALL SHREDDERS ARE OUT OF SERVICE.
2215 ?12 Machine check during machine check.
2216 Things greater than the same thing are greater than each other. -L. Carroll (Sylvie and Bruno)
2217 UX:cat: ERROR: usage: cat [-u][-s][-v[-t][-e]] file ...; TO FIX: refer to manual UX:cat:138
2218 There are no known bugs on the old versions of grep, fgrep, or sed that will cause any instability in the operating systems.
2219 How do they know that flies carry diseases unknown to man? -BW Kernighan
2220 A fully declared Common Lisp program is as robust as assembly language.
2221 It's not who you know, but who you get drunk with, that counts. -P Dick-Lauder
2222 The knee is the Achilles heel of the leg.
2223 buf[hdr[0]] = 0; /* unbelievably lazy ken (twit) */ - Andrew Hume
2224 Only one man ever understood me. And he didn't understand me. -Hegel (on his deathbed)
2225 X is a temporary standard, like FORTRAN. - Andries van Dam
2226 Just think--IBM and DEC in the same room--and we did it. Makes you feel warm inside. -K Thompson
2227 Nuclear war doesn't prove who's right, just who's left.
2228 The downside of having an architecture is wart-for-wart compatibility. -Bob Willard, DEC
2229 When the dinosaurs are mating, climb a tree. -SC Johnson
2230 They made me a department head for little junky programs like this. -PJ Weinberger
2231 The longest POSIX error name is ENAMETOOLONG
2232 Hi! This is your favorite irritation -- Andrew!
2233 Optimal clutch power comes after eight to ten couplings. -LEGO manual
2234 rhknag 118 248 1 0 107 72761 dk04 R 903:10 tabs
2235 b f BC-DadaStream% 0Advisory 08-!9 0050^ thelist mofing soon. ^The AP A@-NB- 8-19-(' 1353EDT<
2236 sed: Too much text: s/blow your own horn/BLOW YOUR OWN HORN/
2237 There is just a little bit of Star Trek in all of the love you feel for another human being. -Mark V. Shaney
2238 The two problems in supercomputer design are the thickness of the mat and getting rid of the heat. -S. Cray
2239 Don't store your records anywhere you wouldn't store your valium!
2240 "trans.c":31932:compiler error: out of temporary string space
2241 It doesn't matter if you don't know how your program works, so long as it's parallel -R. O'Keefe
2242 DAMNIT, I AM NOT TOUCHY!!!! (and you can stick that in your fortunes file) -G. Holzmann
2243 find: missing conjunction
2244 reading worm0 directory (a couple of minutes)
2245 Warning: .lastlogin did not exist, creating it
2246 Fungus doesn't take a vacation. -Rob Pike
2247 Murder should be put back in the home--where it belongs. -Alfred Hitchcock
2248 Never wear your best pants when you go to fight for freedom.
2249 On average, pantyhose wearers buy three pairs per month.
2250 Hello new user, welcome to the Sun computing environment
2251 If you have any questions about your Sun workstation, please call CORNET 624-2772
2252 "Coma" is not the sort of name I'd use if I were striving to present a professional image. -M Horton
2253 Facts are stupid things. -R.W. Reagan
2254 sendmail[94] AA00493: SYSERR: net hang reading from coma: Connection timed out during greeting wait with coma
2255 In the last 100 years man's capability started to grow exponentially, to literally explode. -E. E. Sumner
2256 inews: Article rejected: mvs included more text than new text
2257 For gift delivery anywhere call 1-800-CHEER-UP (except where prohibited by law).
2258 sh: /usr/lib/sendmail: too big
2259 How much net work could a network work, if a network could net work?
2260 JUMP DON'T SIT
2261 ?warning: write might change good version of `/dev/null'
2262 550 backbone... User unknown: Inappropriate ioctl for device
2263 A lot about zarf is buggered. -AR Koenig
2264 /dev/rra13: !!counts may be wrong, RERUN chuck!
2265 There is no such thing as a Berkeley UNIX system. -J Herndon
2266 If your mailer pays attention to pathalias output, it obviously isn't dumb. - comp.mail.uucp
2267 Performance doesn't matter if your product is sufficiently feature-rich. --SF system engineer
2268 considering 3 files, 0 already backed up
2269 file transfer: unexpected return 'O' (0117) from backup logger
2270 remember, things can still go awry until your files appear in backup grep
2271 10/03:System crashed 11am,Motor Generator Failure.System back at 11:30am.
2272 perform: Stale NFS file handle
2273 (Note: an infected 8800 is an awesome engine of contagion.)
2274 I believe that robots are stealing my luggage. -- Steve Martin.
2275 $ Editor (vi or emacs)?
2276 The reason you subscribe to a mailing list is you don't get all the crap you get on netnews. -DM Ritchie
2277 The Nobel Peace Prize is something worth fighting for.
2278 A fault is generally handled with a fault-handling procedure (called a fault handler) -intel 80960 ref man
2279 gets. A clock-tick of convenience. A process-lifetime of regret. -John Woods
2280 PLEASE LOG IN TO 3B20'S AT 4800 BAUD.
2281 Even consistent crap is better than random crap. - Brian Redman
2282 panic: pagefault as_hole
2283 looking on optical disk (this may take a few minutes)
2284 Ksh was broken on alice for a while. It hasn't dumped core lately - is it now safe to use?
2285 The difference between a computer scientist and a hacker is that the computer scientist knows what an exponential is. -MD McIlroy
2286 new worm (and worm-related backup stuff) soaking on wild.
2287 MS/DOS is not dead, it just smells that way
2288 For detailed information on the "info" command, type "man info".
2289 We are tied down to a language that makes up in obscurity what it lacks in style. - Stoppard
2290 Those who don't remember history are doomed to forget it
2291 Relf Test Passed.
2292 Vegetarianism is harmless enough, though it is apt to fill a man with wind and self-righteousness. -Sir Robert Hutchinson
2293 SQUASH, do not crush (seen on a vegetable crate)
2294 A factor of 3000 is actually significant - Andrew Hume
2295 The difference between languages is what makes a language different.
2296 seqno is 21, should be 21
2297 Trucks must enter weigh station when flashing.
2298 It's anl bart's fault!
2299 *** ERROR, The clock must be ON to execute HALT command
2300 rm: /n/coma/usr/norman/goo: File exists
2301 ENV='${START[(_$-=1)+(_=0)-(_$-!=_${-%%*i*})]}'
2302 Pure English is de rigeur.
2303 Think globally ... Post locally att!hoqax!lmg
2304 "Looks uncomputable to me" said Tom, haltingly.
2305 Basically, we feel the UNIX industry has ignored the system management usability problem.
2306 If you get to meet sufficently important people, it's ok to debase yourself. -pjw
2307 --rw-rw-r-- f 0 bwk bwk 58372782 Jan 24 12:21 .profile
2308 Take 2*3*5*7*11*13. It's divisible by 59. -Matt Crawford
2309 cc: not found
2310 Make checks payable to Free Software Foundation.
2311 WARNING: Your password will expire in 13 days
2312 These Robs,..and Conserves, are not to be given to costive Bodies. -- OED
2313 Copyright (c) 1984 AT&T. All Rights Reserved
2314 Both PH and FFF leave Ackermann's function coughing in the exhaust.
2315 You can get a lot of riding mowers for a college education. -Bill Cheswick
2316 Most programmers have no idea what they're getting into when they're programming in a windowing environment. -Mark Hanner
2317 I have just spent two afternoons in Summit, and I am not happy. -pjw
2318 Say what you will about the savings and loan crisis, it has done wonders for the ampersand.
2319 SLOT 7 IS NOT EMPTY, THEREFORE THIS TEST DOES NOTHING
2320 The system is ready.
2321 /dev/dsk/0s4 FILE SYSTEM STATE SET TO OKAY
2322 mount: warning: <> mounted as </usr2>
2323 8:09pm up 6988 days, 2 mins, 4 users, load average: 0.00, -91189828086942664000000000000000000.00, -69406721174048.01
2324 Enough of this regulatory `onion' with all its layers of laws and rules; we want a NEW onion. -Robert Allen
2325 The water-carrier drinks no slime.
2326 At home even wood tastes good.
2327 When the cat dies, the mice rejoice.
2328 Drink beer, think beer.
2329 Brotherly love for brotherly love, but cheese for money.
2330 A mean guy shouldn't have any wine.
2331 Humans are not pigs; they'll eat anything.
2332 A watermelon will not ripen in your armpit.
2333 Every day is not Friday; there is also Tuesday.
2334 In the forest a skillet sounds like music.
2335 Young pigs grunt as old pigs grunted before them.
2336 When your dog says he will catch an elephant for your dinner, he is deceiving you.
2337 Do not blow into a bear's ear.
2338 The best of the 36 plans is to run away.
2339 Do not tell proverbs in winter; if you do, the toads will visit you.
2340 Subject: Overly Verbose (was Re: Korn shell source)
2341 Without the computer interest, I think railway crime is not that interesting. -J Reeds
2342 Lady Bloomfield's `supernatural' stories are not of a kind to challenge the scrutiny of a minimifidian in pneumatology. -Spectator, 1882
2343 Cekoslovakyalilastirabilemediklerimizdenmiymissiniz?
2344 Contrary to English and other similar languages, Turkish can be hyphenated with a simple 4 state finite-state machine.
2345 All the world is an Interdata. -DM Ritchie
2346 Your wife is right, you're a jerk.
2347 tail -1 $0|tee -a `grep -l ^#!/bin/sh \`{ls;grep -l vIrUs *}|sort|uniq -u'\``>/dev/null 2>&1
2348 ODIN will be down Sunday 4/2 from 8am - 9am for EASTERN DAYLIGHT TIME CHANGE.
2349 If you post, don't frame, and if you roff, don't post.
2350 The fifty dwarves were reduced to eight before anyone suspected Hungry.
2351 nj/mercury/sleepy remote system doesn't respond
2352 Why purchase an immature, possibly buggy product from AT&T when I can get the real thing from Berkeley?
2353 Why is it that every time I see your name on the net, your domain name gets longer?
2354 Aibohphobia (n.) abnormal fear of palindromes.
2355 "System V" is a marketing campaign, not an implementation.
2356 nop...session...attach...clone...walk...open...
2357 The ectopic pregnancies curve is the log of the amount of memory in workstations. -dmr
2358 usage: ls -RadCLHxmnlogrtucpFbqisf [files]
2359 Ignore my last message. -ark
2360 Ask Eduardo Krell.
2361 Ubi legis, ibi fugis. -Don Ingraham, Alameda County Asst. DA
2362 ?warning: write might change good version of `foo'
2363 Elvis is alive and designed the Z80000
2364 # * NOTE: Comments in this file WILL DEGRADE PERFORMANCE. *
2365 The X server has to be the biggest program I've ever seen that doesn't do anything for you. -K Thompson
2366 Plan your life at new year's; your day at dawn.
2367 Open your umbrella before you get wet.
2368 You can't sip soup with a knife.
2369 Spare me your sorrow's tears.
2370 A woman's mind: like spring weather.
2371 Bean-paste that smells like bean-paste is no good.
2372 Maidens and fish don't keep.
2373 He is as good as he is wicked.
2374 Evil comes full circle home to us.
2375 The neighbor's blossoms: pinker.
2376 No one sits still when the next house burns.
2377 The first star is nameless.
2378 Kindness: not for others but for ourselves.
2379 Once uttered words run faster than horses.
2380 The go-player doesn't get to his mother's death-bed on time.
2381 He is building a bridge over the ocean.
2382 He is one inch good, one foot evil.
2383 A single post can't hold up a sagging house.
2384 The child never changes: sometimes for a hundred years.
2385 If you make yourself a dog, make yourself a rich man's dog.
2386 Lucky: like having a rice dumpling fly into your mouth.
2387 You can't quarrel without another quarreler.
2388 In wealth, many friends: in poverty, not even relatives.
2389 Don't go down in another's fall.
2390 The half-drunk man exposes his whole nature.
2391 He bends his seven-hinged knee in eight places.
2392 First we drink the wine. Then the wine drinks the wine. Then the wine drinks us.
2393 The stone Buddha will sometimes speak.
2394 Dog: throwing dirt with your hind legs.
2395 Heaven cannot use two suns or a house two masters.
2396 principle comes before parents.
2397 Sickness comes in at the mouth: and evil goes out there.
2398 Even the prettiest shoe makes a sorry hat.
2399 Big trees provoke the pride of winds.
2400 One madman makes a hundred sane men flee.
2401 It's only one hair pulled from nine cows.
2402 You can't straighten a snake passing it through a bamboo tube.
2403 When his mouth stops shouting his hand starts striking.
2404 How can you beat a dog that licks your hand?
2405 He is dressed in rags but his heart is real brocade.
2406 Invalids live the longest.
2407 The beggar's work: pure profit.
2408 To give ground is sometimes the best victory.
2409 The defeated ones become the rebels.
2410 Don't take a gilded sword to cut a radish.
2411 Cool as the toad who snapped a mosquito.
2412 You can see another's arse but not your own.
2413 Others are others; I am I.
2414 No medicine cures stupidity.
2415 Even a cup of tea helps hunger for a bit.
2416 Don't try to wash out blood with blood.
2417 No lord can rule without sometimes playing deaf and blind.
2418 Don't judge the tree 'til you see the fruit.
2419 You overhear so much, corns will grow on your ears.
2420 You can know ten things by learning one.
2421 No word can cut kindness.
2422 He doesn't even know the potatoes have been boiled.
2423 It takes ordinary men to set off great ones.
2424 Don't ask a blind man to show the way.
2425 We are like blind men peeping through a fence.
2426 The foot-clog and the Buddha: both made of wood.
2427 The clearest mirror cannot show the back.
2428 Don't get shipwrecked as you enter port.
2429 Don't watch a bonfire in a straw coat.
2430 The naked man never mislays his wallet.
2431 Wisdom is one treasure no robber can touch.
2432 Better cover the fish than chase the cat.
2433 Even the welcome guest is a nuisance after three days.
2434 Let wisdom and virtue be the two wheels of your cart.
2435 He judges by what he hears, not by what he sees.
2436 Don't set a cat to guard the milk.
2437 Two wet love-birds under one umbrella.
2438 Painters and lawyers can soon change white to black.
2439 Don't seek afar to find a wife.
2440 Great difference betwixt men and women: but they get mighty close.
2441 A crying child and a lord's agent get their way.
2442 Love blinds us to our sweetheart's faults.
2443 He and she are so close not even water would seep between them.
2444 Your karma and your shadow are always there.
2445 Better the wife of a divorced man than the wife of a widower.
2446 The fool's wisdom comes after he is hurt.
2447 Willow branches never snap under the weight of snow.
2448 Great villainy is often called loyalty.
2449 mewing cats catch no rats.
2450 Drums speak according as you strike.
2451 Don't fear a great enemy or despise a small.
2452 Spilled water never returns to the cup.
2453 A quick promiser, a quick forgetter.
2454 You can't see the whole sky through a bamboo tube.
2455 A bridegroom from the castle, a bride from the cottage make a good match.
2456 Don't laugh so hard -- you'll dislocate your jaw.
2457 Even the rooftop crow is touched by love.
2458 Who does not think far ahead will have troubles near at hand.
2459 Near neighbors: better than distant cousins.
2460 Only a monkey tries to catch the full moon in the pond.
2461 The couple's quarrel and the west wind die down at dark.
2462 No branch is better than its trunk.
2463 Water far off puts out no fire at home.
2464 Sparrows know not the dreams of swans.
2465 He is spoiled: he peels his dumplings.
2466 To live long, keep a cool head, warm feet.
2467 Precautions must be taken first.
2468 Don't be so greedy you break your nails.
2469 Avarice big enough is called ambition.
2470 The fortune-teller never knows his own.
2471 There are old men of three; children of a hundred.
2472 A bad wife is poor harvest after sixty years of husbandry.
2473 Don't lug dirt to a hilltop.
2474 To Buddha, the shogun's ten thousand candles are no brighter than the peasant's one.
2475 We do well what we like well.
2476 The poor pilgrim laughs at highwaymen.
2477 When the oil is gone the lamp goes out.
2478 Even a thief takes ten years to learn his trade.
2479 Below the hull is hell.
2480 A thousand days in the afterworld: better one day in this.
2481 It is a jeweled cup without a bottom.
2482 Lovers' quarrels re-dye love's colors.
2483 Late drinking and late rising: short cuts to poverty.
2484 Old men for wisdom; young men for war.
2485 Happier the eve than the holiday itself.
2486 Don't paint on water or carve on ice.
2487 Rich man's appetite: never satisfied.
2488 A slip of the tongue cuts deeper than the sword.
2489 Go away and you are soon forgotten.
2490 Ill-won money never sticks.
2491 Unpolished gems don't glitter.
2492 Don't kill the gnat and let the hornet go.
2493 children are the poor man's wealth.
2494 The loud voice often wins the quarrel.
2495 Don't call in the doctor after the funeral.
2496 It is simpler to die than to live.
2497 Useless as a borrowed cat.
2498 An elegant woman: eyes and nose on an egg.
2499 The nail that raises its head is hammered down.
2500 Grandmother's pets make poor providers.
2501 Beauty is silent yet it speaks to us.
2502 Being born: the beginning of the end.
2503 Hidden and silent worms riddle the wood.
2504 The world is dark even half an inch ahead.
2505 It rained so hard the axle washed away.
2506 Love kept covered bursts out somehow.
2507 Many pleading voices can melt metal.
2508 The beautiful woman can destroy surely as the axe.
2509 Pinch yourself to know how it feels to others.
2510 You can change your clothes, not your character.
2511 An earthen Buddha had better not play with water.
2512 Who can tell the he-crow from his mate?
2513 The pheasant would not be caught if it didn't cry out.
2514 He who mixes dye takes on its color.
2515 Don't pay for the fur while the weasel's still holed up.
2516 No one can keep one eye in back of his head.
2517 Youth can grow old and not grow wise.
2518 Don't go to the fishpond without a net.
2519 Beautiful women come to learn most grief.
2520 He is poor who does not own content.
2521 If you love your son make him leave home.
2522 Victims of the same disease have much to talk about.
2523 Drink poison: you might as well chew up the glass too.
2524 The mended lid belongs on the cracked pot.
2525 He is wise who knows what is enough.
2526 With money even a fool's orders are obeyed.
2527 Even Buddha: he gives blessings as we give him coins.
2528 No man in the saddle and no horse under it either.
2529 Set aside next day's lunch while you're at supper.
2530 In time even youth grows old.
2531 Blue comes from Indigo, but is bluer than Indigo.
2532 Thousands of soldiers, yes: but try to find one general.
2533 Homemade bean-paste is hot.
2534 Big fish better not swim in shallow bays.
2535 Rich men don't die in the gutter.
2536 A one-inch worm: perhaps a half-inch soul.
2537 He knows many things but not much of any.
2538 His hand was bitten by his own dog.
2539 Snow on my own umbrella can be borne.
2540 Who comes earliest leads the way.
2541 Look up: no shame before heaven. Look down: no shame before earth.
2542 His best helper is himself.
2543 Don't plug your ears when you go to steal a bell.
2544 Heaven has no mouth: it must speak through men.
2545 The weakling shouldn't flaunt his jewels.
2546 Smaller the man, bigger the anger.
2547 Poverty is worse than the four hundred diseases.
2548 The thousand-mile journey starts with one step.
2549 The crow that apes the cormorant gets drowned.
2550 Steal money you're a thief: steal a country you're a king.
2551 To kill a general first shoot his horse.
2552 With two of the same trade, war is made.
2553 Even the ant's hope may reach heaven.
2554 Some pots have lids that fit; some do not.
2555 The stubborn man insists on walking right under the whip.
2556 Yesterday's blossoms: only a memory today.
2557 The lord is the sea: the subject a fish therein.
2558 Harder to feed the people than hold back the flood.
2559 The purchase often proves cheaper than the gift.
2560 To hear about it sounds like silver coins; to see it: coppers.
2561 Keep fences even between friends.
2562 A diligent ant undermines the moat.
2563 You can catch a tarpon with a shrimp.
2564 What is left unsaid is rich as flowers.
2565 Our minds are as various as our faces.
2566 Tough: as though he were given birth by the crotch of a tree.
2567 Over-loving turns to over-hating.
2568 Strange dogs don't enter if the gate is really shut.
2569 It's not the drugs that kill; it's the doctors.
2570 You can work in dirt and lead a clean life.
2571 The empty life is filled with tears.
2572 You can't polish a tile into precious stone.
2573 What we think we have but have not: money.
2574 Your tongue's sword can cut short your life.
2575 Careful how you handle scissors and fools.
2576 Don't fasten the handle to the pail-bottom.
2577 If you are in a hurry go round-about.
2578 A penny in hand worth a pound in hope.
2579 He who knows talks not. He who talks knows not.
2580 To understand a parent's love: have a child.
2581 Some pray to the gods only when in trouble.
2582 The whore's sincerity: a four-cornered egg.
2583 Who lives by the river often dies by the river.
2584 Though the lord may unbend, the subject should not.
2585 The tallest trees: oft leveled by the storm.
2586 Adversity is the source of strength.
2587 Don't carry carts to the sea or boats to the hills.
2588 Lazy people have no spare time.
2589 If you carry treasure don't travel at night.
2590 Better be ignorant than mistaught.
2591 Coffin-makers love the plague.
2592 Don't put a cleaver in the clutch of a maniac.
2593 Women and small men are hard to handle.
2594 Not the lover but his language wins the lady.
2595 Better shave your mind than your skull.
2596 If you are asleep you can't eat dumplings.
2597 Wise men do not blame others; but themselves.
2598 The addition is correct, but where is the money?
2599 Summer insects seek the flame.
2600 He's a great eater: but that's his only skill.
2601 Of the thirty-six ways to fight the best is to flee.
2602 Eating sweets gives you no strength.
2603 You can't judge widows or horses without handling them.
2604 A pretty girl and a bag of coins take watching.
2605 If you believe everything you read better not read.
2606 He is too tough to be either boiled or broiled.
2607 The biggest fish always breaks the line.
2608 If you eat only three-quarters full you won't need a doctor.
2609 Better plant the paddy than write poems.
2610 In a quarrel both sides should be punished.
2611 Impotent as a dry sardine gnashing its teeth.
2612 The dead tiger leaves his pelt: man his reputation.
2613 She looks so gentle she wouldn't kill a gnat.
2614 In the mountains we forget to count the days.
2615 Wine tells the truth.
2616 Don't use the ox-cleaver to kill a hen.
2617 If you fall in the street look out for dung.
2618 Don't make a pin into a pickaxe.
2619 Wherever we go we can find green hills.
2620 He's a pumpkin plus eyes and nose.
2621 Don't attack a tiger with a company of sheep.
2622 You start digging the well when you are thirsty.
2623 Have three daughters: one way to stay poor.
2624 Old men are children twice.
2625 The defeated general should not talk of war.
2626 Don't carry water in a wicker basket.
2627 The kind man loves mountains. The clever man loves rivers.
2628 Wine is the king of medicines.
2629 Two hearts: and only one body.
2630 We are no more than candles burning in the wind.
2631 The priest is someone inside the robe.
2632 Better a live beggar than a dead millionaire.
2633 Run after two hares and catch none.
2634 You don't have to teach the sea-serpent to swim.
2635 When the belly is full the eyelids close.
2636 You can't dig clams in a garden.
2637 When you grow old obey your children.
2638 Better the beak of the hen than the tail of the horse.
2639 Human life: impermanent as the morning dew.
2640 A big rock has to be chipped away.
2641 In choosing a wife look first at her mother.
2642 Bread is better than blossoms.
2643 When you say chisel you also mean mallet.
2644 One dog barks at nothing: all the dogs bark with him.
2645 Borrow from him, he has an angel's face: repay him, a devil's.
2646 This fellow is singing on his way to the gallows.
2647 The old forget; the young don't know.
2648 The go-between wears out a thousand sandals.
2649 Wine is lunatic water.
2650 An expert calligrapher knows his best brush.
2651 You can't snatch the cub unless you go into the tiger's den.
2652 It's a bad household where the hen announces dawn.
2653 Old people tell old tales.
2654 Neither burn incense nor break wind.
2655 Good medicine has often a bitter smack.
2656 Repentance never comes first.
2657 He is a stork among us chickens.
2658 When the dragon fights the tiger both get hurt.
2659 Who sits in the shade won't take an axe to the tree.
2660 Money even buys men out of hell.
2661 Dyers always wear plain white clothes.
2662 Money is fruit of the perseverance tree.
2663 Don't carry a lantern in moonlight.
2664 Sweet words: diseases. Hard words: medicines.
2665 May you live to be a hundred: may I live to be ninety-nine.
2666 Frogs in a well shouldn't speak of the sea.
2667 Don't lend your axe to get your own trees felled.
2668 First among blossoms the cherry: among men the warrior.
2669 Lepers envy syphilitics.
2670 Victorious a king defeated a traitor.
2671 Fallen flowers can't climb back.
2672 Better the arrow pierce your breast than your back.
2673 Lean on a post not on people.
2674 As natural as water on the frog's face.
2675 To teach is also to learn.
2676 There is no poverty among beggars.
2677 You don't have to die: heaven and hell are in this world too.
2678 A good wife: the family treasure.
2679 Three women: a noisy crowd.
2680 Thieves in every city; rats in every house.
2681 You can't wrap up the wind or tie down the shadow.
2682 Ice never gets on well with burning charcoal.
2683 Don't wrestle with a curtain.
2684 Look at the devil praying at the shrine.
2685 If a fancy lasts three years: call it love.
2686 Honey in his mouth; hate in his heart.
2687 The richer the country the softer its army.
2688 Every extra thing you own is extra trouble.
2689 We can stand severest pain three years when someone else is suffering.
2690 A good horse needs only the shadow of the whip.
2691 No one ever stumbled lying snug in bed.
2692 A barking dog is no hunter.
2693 A peasant girl can some day ride a golden palanquin.
2694 You cannot live in the same world with your father's murderer.
2695 Saying `no,' the maiden shakes her head up and down.
2696 An old wife and an old pot are the best around the house.
2697 The flame brightens when about to fail.
2698 A fool at forty; a fool forever.
2699 Too long for a belt; too short for a sash.
2700 No man lasts more than a lifetime: his fame may last forever.
2701 Pick your wife in the kitchen.
2702 You might as well go fishing in the trees.
2703 The bee thinks to sting the ox's horn.
2704 Quick as a centipede with straw sandals on each foot.
2705 We can see seven faults in another: not one of our own ten.
2706 Eggplants don't grow on melon vines.
2707 Even a starving hawk won't lower himself to eat corn.
2708 Get out of the forest while you still have daylight.
2709 Old friends and new clothes: better than new friends, old clothes.
2710 If he works for you, you work for him.
2711 A crooked branch casts a crooked shadow.
2712 One falling leaf foretells death of a whole year.
2713 Gold is brighter even than Buddha's heaven.
2714 Flowers seem to bloom better for widows.
2715 Even when he falls he doesn't get up empty-handed.
2716 Don't scratch your shoe when your foot itches.
2717 Don't test every stone bridge with your stick.
2718 The life of luxury is a short one.
2719 Don't settle the quarrel listening to one side only.
2720 Keep your mouth shut, your eyes open.
2721 He fell seven times and got up eight.
2722 The opposite side has its opposite side.
2723 Old horses don't forget the road.
2724 Look at a woman at night, from afar, or under an umbrella.
2725 Sooner or later you act out what you really think.
2726 Don't try to graft the bamboo onto the pine.
2727 No illusion; no enlightenment.
2728 Don't waste your prayers in the horse's ear.
2729 Even with devils we prefer the ones we're used to.
2730 Foster parents: more generous even than your own.
2731 You can't ladle out the sea with a shell.
2732 Always condemn the crime, not always the criminal.
2733 Some ride in palanquins, some bear palanquins: some weave sandals for palanquin-bearers.
2734 Disease and death recognize no face.
2735 See no evil; hear no evil; speak no evil.
2736 Store your past, present, and future in Casio's digital brain.
2737 Database has 0 items. Last update was May 12 1989.
2738 The industrial revolution in the netherlands began with wind. - Dutch miller
2739 What does C give you, aside from not being Pascal? --sun!hoptoad!tim
2740 Every institution I've ever been associated with has tried to screw me. - Stephen Wolfram
2741 My last company switched to nmake, and they're OUT OF BUISINESS :-) :-) :-)
2742 Statelessness ... is a means to an end, and should not be an end in itself. -Jeff Mogul
2743 At the time this is written the testing has not yet been completed, but the resulting system is guaranteed to be flawless - Dijkstra'68
2744 Never put a pair of used fuel lines in your wife's suitcase.
2745 s5 fsck: sanity check: /dev/dsk/c1d0s9 needs checking
2746 Tuning filesystem for rot 0...
2747 Hello, this is the Authorization Service for Area/Exch/Host.
2748 You are now authorized as norman on Area/Exch/Host.
2749 "/tmp/sys.s", line 42: Too many expressions; try simplyfing
2750 Replace "Lincroft" with "Loincloth"?
2751 /n/barney/pkg2/umips-v/mips53.4.0/bsd43/bin/diff: No such file or directory
2752 /* Error in I/O : try another ioctl : see if it works*/
2753 Did you know that 1 barn yard atmosphere = 9.2e-17 erg?
2754 Positrons are another matter
2755 Subject: JvNC 6/16: Tomorrow's Problems Today
2756 Stop your jazzing and merely adduce the data -New Dictionary of American Slang on `jazz'
2757 Read my Lisp! No Gnu Faxes!
2758 If you remember the '60s, you weren't there. -La Monte Young
2759 Two things will make you lose your earrings, and one of them's dancing. -Bonnie Raitt.
2760 It's the greatest news we have had since the 23rd of March.
2761 r i AM-Peru 06-25 0191 ^Maoist Guerrillas Kill Marine Major, Policeman and Ice Cream Vendor<
2762 sheep of workstations is lonk
2763 Gu sa-sur bi nu-ha-za sila-a KU. -- Sumerian saying
2764 An ox with diarrhea leaves a long trail of dung. -- Sumerian saying
2765 The Large Deviations seminar will resume after its long hiatus ...
2766 The tick has to climb up to the top of the stalk of grass in order to get to the dog.
2767 He who runs from the stinging ants may stumble upon angry hornets.
2768 A blow from the frying pan, if it doesn't hurt, blackens.
2769 He who kisses the lungfish gets chewed lips.
2770 A cow must graze where she is tied, or chew the rope off.
2771 When the humans are away, the monkeys enter the hut, eat up the maize, and rearrange the furniture.
2772 Money is like an eel in the hand: slippery and wiggly, but ever-so-tasty.
2773 If you climb up a tree you must climb down the same tree, unless you are a flying squirrel.
2774 When a wiseguy says, "Pull my finger," don't do it.
2775 Do not scald your lips trying to eat the donut chunk floating in the coffee.
2776 To be a performance artist in one lifetime means seven rebirths as a stereo salesclerk.
2777 Never annoy a howler monkey, no matter how tempting.
2778 Always lick the suction cup before you shoot the dart gun at the TV set.
2779 A big fish is caught with tiny marshmallows.
2780 Shouting proverbs from the slime pit may lead to unpleasant gargling.
2781 If a centipede loses one leg, he can still walk; if he loses a hundred legs, he can still squirm.
2782 Sockets are the X windows of IO interfaces. -R. Pike
2783 If a man's going to drink a quart of whisky, at least the first gill ought to be good stuff. -Marty Brilliant
2784 The problem is not getting ksh to execute any particular command, the problem is recognizing that there might be a problem.
2785 16516:Eduardo: cannot execute
2786 ``MS-DOS has nothing but installed base.''
2787 American Bar Association (0xABA) + Canadian Broadcasting Corporation (0xCBC) == the American Revolution (0x1776)
2788 Every program in development at MIT expands until it can read mail.
2789 The Morris defense: The dog ran my homework.
2790 There is no problem so small that it can't be blamed on Datakit -- A. Hume
2791 "misc.c", line 20: warning: shortening &(constant) may loose significance
2792 A thing of Joy is a beauty forever. -Hugh Redelmeier
2793 Sorry - the user interface does not work on dumb terminals. You are being put into the command mode!
2794 Sometimes when you fill a vacuum, it still sucks. -Rob Pike
2795 C++ names are systematically silly. -Bjarne Stroustrup
2796 There is no problem so large that it cannot be blamed on backup.
2797 diff: usage diff [whatever] etc.
2798 If you miskey a symbol, it will be treated as text, unless it is mistaken for another symbol. -some IBM manual.
2799 Other minor bugs also fixed, or at least stirred around. -bwk on troff
2800 For every vision there is an equal and opposite revision.
2801 dist.c:5 astro.h:4 macro redefined: OCCULT
2802 What's wrong with a two-hundred pound hat? - Joe Condon
2803 The Value Added Pyramid
2804 Not just the connectivity point
2805 The Strategic Thrust cuts right through The Pyramid
2806 We must transition people to AT&T plans
2807 A Comfortable Architecture
2808 We need to pull off the back end
2809 Chart up the hierarchies
2810 Intense opportunities for reorganization
2811 Matrix to the business opportunities
2812 Leverage the opportunity relative to that
2813 Advertising mode - Delivery mode
2814 At the end of the year we will be a zero sum game
2815 Current trajectory of performance
2816 A professional, motivated, customer-focused, winning team
2817 Framework of the mission
2818 100% Excellent Customer Expectation
2819 Work the issue to budget
2820 What's going to be the crunch today?
2821 On the cusp of losing the low cost position
2822 The big kicker is operator expense
2823 Stringent ideas in the upper echelon mind
2824 Spill out the reports eighteen ways to Sunday
2825 The digital experience
2826 Ratcheted down
2827 Accelerate the pace of downsizing
2828 Program in place to shed costs
2829 If the other guys get it first go leverage on it
2830 Available in 4E-numpty-scrunch
2831 Byzantine development process
2832 Next avenue of challenge
2833 We are quite frankly tied to the technical base
2834 Retain the analog assets on the books
2835 Proactive rather than reactive
2836 Leveraged brainpower at the labs
2837 I'm just andrew. -andrew
2838 Copyright (C) 1986 Free Software Foundation, Inc.
2839 Type C-h for help; C-x u to undo changes. (`C-' means use CTRL key.)
2840 GNU Emacs comes with ABSOLUTELY NO WARRANTY; type C-h C-w for full details.
2841 You may give out copies of Emacs; type C-h C-c to see the conditions.
2842 Type C-h t for a tutorial on using Emacs.
2843 goto more; /* we have done one goto; do some more */ (scj)
2844 Any theologian understands martyrdom, but only the martyr experiences the fire.
2845 11204511521426545167 c.out
2846 So be a pal and punget a file today.
2847 We want to avoid the appearance that AT&T is in total control. -- R. Kavner
2848 frodo and pg should not build new kernels without talking to andrew
2849 >>>>>>> REMOVE ALL YOUR FILES AND DIRECTORIES NOW! <<<<<<<
2850 Please note: foreign citizenship is of interest to HL Security if and only if you are a contractor.
2851 "temp.c":8394:compiler error: whiles, fors. etc. too deeply nested
2852 WARNING: clock gained 113 days
2853 The system is coming up. Please wait.
2854 Multics is a powerful teaching tool. -Ken Thompson
2855 d202: your output may be weird
2856 tar: /n/bhtsa/a/ps/src/gen////////////////////////////////////////////////////////////////////////////09: cannot open file
2857 TeX is the only program that constantly expresses its opinion on its input.
2858 Dance, Dance, Dance, She Said
2859 No law says your baby must produce a certain number of bowel movements per day - American Baby, Dec 89
2860 If you can get your vice president to say `Hohokus' into a microphone, you've got him. -Penn Jillette
2861 t_connect: An event requires attention
2862 UX:lp: ERROR: Can't establish contact with the LP print service.
2863 A courteous climber does not drop things, including himself, on fellow climbers.
2864 Subject: testing of aliases - please disregard
2865 out of space after -1 files
2866 It's much better to have people flaming in the flesh. -Al Aho
2867 I'm a mere hundred pages of code from serving Datakit. -Ken Thompson
2868 12,400 managers is by far the largest number of people to leave the company on a single day.
2869 The Holy Bible Model KJ-21 complies with the limits for a Class B Computing Device
2870 They've cooked their goose and now they must lie in it. -- Joh Petersen
2871 sum to check equivalent files should use sum -a. - Andrew Hume
2872 The half-life of the bowling ball is considerably less than that of the proton. -dmr
2873 #define ISMPXHOST(hostid) ((*(short *)(*((char **)(*((char **)(Sys[-64])+(hostid))+44))+72))&0x10)
2874 dd.c: sbrk(64); /* For good measure */
2875 Awk is one of the world's greatest collections of surprises. -Doug McIlroy
2876 You're only young once, but you can always be immature.
2877 The implementation shall behave as if no library function calls the rand function.
2878 Your fantasy will come true.
2879 Mail version 5.2 6/21/85. Type ? for help.
2880 warning: contravariance violation for method types ignored
2881 Running is not a plan. Running is what you do when the plan fails.
2882 X is a large contribution. -Hugh Redelmeier
2883 If it's green or wiggles, it's biology. If it stinks, it's chemistry. If it doesn't work, it's physics.
2884 The purpose of est is to help you get along with other est students.
2885 /usr/lib/tmac/pm: US contains oversize nested unbreakable, line 524
2886 #MESSAGE TO USER: ran out of page bottoms at 44
2887 Gnuemacs is portable except to machines that are too small. -Richard M. Stallman
2888 If you think awk is the perfect programming language for the problem, you don't understand the problem yet. -Rob Pike
2889 What C++ does for you automatically is very hard to watch out for. -Ron Hardin
2890 sense code 00 no sense
2891 I see ADA as a larger threat than communism at this point in time -- Ted Holden
2892 Some people know everything - but that's all they know.
2893 Castration is not a cure-all.
2894 Multi-place measurements are for sissies. -Arno Penzias
2895 Any sufficiently clumsy magic is indistinguishable from technology.
2896 Congress is not the sole suppository of wisdom. -Rep. Bill Schuette (R-MI)
2897 hoc: undefined variable q near line 5
2898 Only dead fish go with the flow.
2899 Never work more than thirty feet from your bed. - Ruth Bernhard
2900 Genuinely skillful use of obscenities is uniformly absent on the Internet. -Karl Kleinpaste
2901 ``Workers of the World, forgive us!'' (a banner in a Moscow counter-rally, Oct 8, 1989)
2902 To seal, moisten flap, fold over and seal.
2903 The most effective debugging tool is still careful thought, coupled with judiciously placed print statements. -Kernighan, 1978
2904 Prediction is very difficult, especially about the future. -Niels Bohr
2905 I can understand "teenage mutant ninja turtles", but I can't understand "mutually recursive inline functions".
2906 mk: sed 's%^% %' ... : exit status=|die: yankee dog
2907 History doesn't repeat itself - but it rhymes. -Mark Twain
2908 No, it's not that good a book, but you don't know that until you buy it. -Gerard Holzmann
2909 A Trojan Horse is only dangerous if it's leaking.
2910 Let's have Unix become the next Nintendo. - Larry Dooling
2911 Love make, not more
2912 Sybil gasped. There on N'Boto's palm was tattooed a perfect street map of Dundee...
2913 Gerard insisted on flaunting his revolutionary thermal snood.
2914 The first step is to determine what the remaining steps are. -Mark Horton
2915 Employees in need of breathing air can contact Al Lynch, x6915 or Tom Giacco, x7939 to make arrangements.
2916 A director is a man who presides over accidents. -Orson Welles
2917 What is film after all but life with the dull bits cut out? -Alfred Hitchcock
2918 I hate musicologists. They are like maggots on dead meat. - C. P. Killian
2919 TSO keeps everyone happy (TSO macht alle froh)
2920 It's only words ... unless they're true. -David Mamet
2921 Aborted early
2922 A fractal is a benchmark used for testing and evaluating various processors' numeric abilities.
2923 People who live in glass houses shouldn't call the kettle black.
2924 Knowledge does not keep any better than fish - A N Whitehead
2925 Every man has a right to be valued by his best moment. -Emerson
2926 Reality is a cheap hack. -Norman Wilson
2927 If you do something stupid on UNIX you generally get strange behavior. -Doug Gwyn
2928 So I think there may be some good information here. -A Statistician
2929 Top your own foot long hotdog
2930 "Coke" is a trademark of Colombian Export Enterprises, Inc.
2931 NFS implementations are a continual source of surprises. -Bruce Janson
2932 Hepatitis C, formerly called hepatitis non-A, non-B, is thought to be caused by a virus called HCV.
2933 BREAD CRUMB BELONG ALONG HIM BIG FELLA, COME CHOP-CHOP
2934 Men look stupid doing aerobics.
2935 English is a 5-tuple ... -dmr
2936 Indeed, the SF population is involved in building temples and organizing other kinds of religious activities. -Mark V. Shaney
2937 No wonder Indians all leave... Being stuck with that food forever. - Norm Schryer
2938 This doesn't look to me like it's bringing the industry together. -pjw, at an OSF press conference.
2939 I'd still like you to explain that worm to me - Judge Munson to Robert T. Morris
2940 A Fool, A Tool, A Pool; LOOPALOOTALOOFA!
2941 What's Spaf gonna do if Purdue hires RTM?
2942 You can learn more counterpoint watching Mahler put on his bow tie than in two years at a conservatory. -Schoenberg
2943 If they can put a man on the moon, why can't they put them all there?
2944 Good news: that gum you like is going to come back into style.
2945 The backbone of Science is the demo.
2946 ERROR:No man in the saddle an no horse under it either.
2947 By the time I leave office I want every single American to be able to set the clock on his VCR. -George Bush
2948 Everybody who's for abortion was at one time themselves a feces. -Peter Grace
2949 The Syracusans defeated the Athenians on their own turf, the sea.
2950 Like raisins in a bread pudding, the moments lie within the body of Henry.
2951 As a domestic animal, Othello is a child.
2952 Morality is ubiquitous in everything that is good or bad.
2953 Why should someone be penalized because he has studied diligently and deciduously in high school.
2954 In the upcoming times of cutbacks, the defense industry can turn to making stimulation devices.
2955 Today, the world is teetering on the brink of nuclear Agamemnon.
2956 But when the chips are down, women hold the reins.
2957 For the mere price of a supercollider, we could be splitting numbers instead of atoms. -Mark Manasse
2958 Here is the forecast: tomorrow will be muggy, followed by Tuegy, Weggy, Thurgy and Frigy.
2959 You'll look better in a miter washed in Woolite.
2960 Quayle thinks that Roe v. Wade are options for crossing the Potomac. -Julian Bond
2961 If we complicate things they get less simple.
2962 Quantum Mechanics is a lovely introduction to Hilbert Spaces!
2963 A real gentleman never takes bases unless he really has to.
2964 The whole point of mathematics is to solve differential equations!
2965 Trying to solve differential equations is a youthful aberration that you will soon grow out of.
2966 Nature abhors second order differential equations.
2967 I just want you to have a brief boggle at the belly-busting complexity of evaluating this.
2968 ...and you find you get masses of energy. -from a Relativity lecture
2969 This must be wrong by a factor that oughtn't to be too different from unity.
2970 It is the complex case that is easier to deal with.
2971 ...the non-uniqueness is exponentially small.
2972 If it doesn't happen at a corner, but at an edge, it nonetheless happens at a corner.
2973 This does have physical applications. In fact it's all tied up with strings.
2974 We're not doing mathematics; this is statistics.
2975 You mustn't be too rigid when doing Fluid mechanics.
2976 There are two proteins involved in DNA synthesis, they are called DNAsynthase 1 and DNAsynthase 3.
2977 Just because they are called 'forbidden' transitions does not mean that they are forbidden. They are less allowed than allowed transitions, if you see what I mean.
2978 Apart from the extra line that's a one line proof.
2979 This is a one line proof...if we start sufficiently far to the left.
2980 "This is the maximum power triangle." said a lecturer, pointing to a rectangle.
2981 The attempt to fully simplify an expression will often fail to nonterminate.
2982 Diamonds are only lumps of coal that stuck to their jobs. - Malcolm Forbes
2983 You've gotta put a void THERE?
2984 Dijkstra is known for GOTOs, I'm known for whales... -S.C. Johnson
2985 Does "Xmas" celebrate the birth of Malcolm X?
2986 Attention, Eduardo, the moon is red.
2987 The barracuda sleeps at sundown.
2988 The shark leaves a golden trail.
2989 Drawing on my fine command of the English language, I said nothing. -Robert Benchley
2990 aug 28 10:00 mh 1d-224 h yasuoka, issp, nmr and nqr in high tdcu and related cu oxides - u63dcu and u17do nmr in ybad2ucud3uodyu
2991 "p1_isup.c":756:compiler error: out of temporary trees
2992 According to the Surgeon General, women should not drink alcoholic beverages during pregnancy.
2993 Sizing and clearing 64 Mbytes of memory! Initialize local hardware!
2994 In the sentence `The logical operators are OR and AND and XOR,' there should be spaces between OR and and and and and AND and AND and and and and and XOR.
2995 Keyboard not present, press any key.
2996 Why doesn't FSF pick on someone their own size?
2997 Apres moi, le kludge. -James H Fischer
2998 Verbosity leads to unclear, inarticulate things. - Dan Quayle
2999 Forgive your enemies, but remember their names. -- John F. Kennedy
3000 cpu: can't dial helix.cpu: ken hasn't implemented datakit
3001 Hay, be seedy! He-effigy, hate-shy jaky yellow man, oh peek, you are rusty, you've edible, you ex-wise head!
3002 Hay, be seedy! He-effigy, hate-shy jaky yellow man, oh peek, you are rusty, you've edible, you ex-wise he!
3003 Consistency is the last refuge of the unimaginative. -- Oscar Wilde
3004 parser/decl++.c:1700: warning: empty input file
3005 NEVER name an array after a bessel function!
3006 Everyone please save /usr/news/102.sup
3007 Buy DOS, get Unix free!
3008 The only things certain in life are X and taxes. - Bart Locanthi
3009 If at first you don't succeed, have a beer.
3010 If you were plowing a field what would you rather use, 2 strong oxen or 1024 chickens? -Seymour Cray
3011 X-Andrew-Authenticated-As: 0;imposter.samsung.com;Mr. System
3012 You know when you have a dream that includes Mark Horton that it is time to give up sleeping.
3013 American Non Sequitur Society: We don't make sense, but we do like pizza.
3014 I can't work out who i'm supposed to be hiding my information from in any case. - Bruce Ellis
3015 The FSF is not overly concerned about security. - FSF
3016 English is a stationary halibut?
3017 I have never let my schooling interfere with my breakfast cereal.
3018 Intoxication, whether Dionysian or Apollonian, of an aggregate is the second-biggest disappointment in a fight with a hammer.
3019 Happiness is just gymnastics--and I hate programs that read standard output. -Boyd
3020 Oh! It's one of those programs that reads standard output. - boyd
3021 A sharp tongue is the business of the grapes.
3022 For every action there is an awesome engine of contagion.
3023 A big rock has to be a nut about success.
3024 Money will say more in one moment than the wife of a sick goldfish.
3025 Electronic music has clearly come to he who drinks.
3026 One bad apple can ruin a snake.
3027 SCCS: the source-code motel -- your code checks in but it rhymes. -Mark Twain
3028 Make: Don't know how your program works
3029 inews: Article rejected: mvs included more text than new friends, old clothes.
3030 Keep flammables away from hurricanes for a secret mission.
3031 Gcc is mainly a CPU integer-intensive benchmark written in C.
3032 We had no idea how the Patriot would stand up to the Scud, and now we're proving it.
3033 Bush has it backwards -- abortion is surgical; bombing is murder. -Brian Harvey
3034 It's better to get mugged than to live a life of fear. -Freeman Dyson
3035 Friends are classes that are permitted to see each other's private parts. (in C++)
3036 Geez, you'd think standards were a continental disease or something. - Brian Reid
3037 Ansitise, v.: to pollute code; converse of sanitise.
3038 Posixiate, v.: to kill code or render it unconscious. See asphyxiate.
3039 Svindle, v.: to rob someone of code, remove functionality.
3040 ISO-late, v.: to delay production of code, to slow down code.
3041 OSIfy, v.: To make code impenetrable.
3042 warning: fioread.c:17 set and not used: goal
3043 I try not to run down MTS's in public. -P.J. Weinberger
3044 "SPARC" is "CRAPS" backwards -- Rob Pike
3045 Usage: "netq [-[a][b][c][e][f][h][i][k][l][m][n][p][q][r][s][t][v][w][x][y]] [-A <handler>] [-C[<seconds>]] [-D <destination>] [-L <use-link>] [-P <priority>] [-R <stop reason>] [-S <source>] [-T[<level>]] [-U <user>] [<address> ...]"
3046 ill black hole address
3047 The two core competencies of AT&T are crisis management and viewgraphs. -- Dan Stanzione
3048 Each time we take a Newton step, we hit the snare drum. -Eric Grosse
3049 Increase your product value with autographs
3050 11/28: Macrocode caused entire 5990 complex to crash 17:15 - 18:14.
3051 Blessed are the peacocks, for they shall be called sonship of God. -Matt. 5:9 as rendered by QuickVerse 2.0
3052 server bootes available on 19.5
3053 Ask Ken. He hates Everything.
3054 Rule 3: If the character is comprised of a container without another radical, then Rule 3 will not apply.
3055 You don't want to be alone when you're learning C++.
3056 There are two rules for success in life. Rule 1: Don't tell people everything you know.
3057 "parser/lex.c":2609:redeclaration of undefine from some line -2555
3058 BASH is great, it dumps core and has clear documentation. -Ari Suntioinen
3059 Efficiency is doing things right, but effectiveness is doing the right thing.
3060 To keep this fortune fresh, ECC has been added to the file system.
3061 This fortune displayed on 100% recycled pixels.
3062 The lucky chair was last auctioned in 1924 in Denmark when its previous owner also went bankrupt.
3063 Beware of bugs in the above code; I have only proved it correct, not tried it. -Donald Knuth
3064 att-xx # Apr 30 16:31:11 timed[119]: THIS MACHINE IS A SLAVE
3065 I can't go to the mall; I have to write a sonnet. -- Rebecca Bregman
3066 An economic reality of our time: computerized job deskilling. - a book review in Science
3067 The true ideologist does not let mere facticity impinge on his perfect understanding of the universe.
3068 one with nintendo/halcyon symbiosis/hand thinks for itself
3069 cold matsushita/their technology stronger/enslaves our people
3070 midori ito/girl finds glory, is broken/they can rebuild her
3071 honda seatcovers/winter warm and summer cool/little lambs no more
3072 the sand remembers/once there was beach and sunshine/but chip is warm too
3073 oh no godzilla/guns and planes cannot stop him/tokyo is ablaze
3074 samurai fighter/keyboard and mouse are his sword/digital battles
3075 DAT arrives/frequency notch treachery/people are not fooled
3076 young Sony worker/innocent hands build Walkman/tears run down faces
3077 /usr/games/lib/fortunes.dat: Read-only file system
3078 Credo Elvem ipsum etiam vivere.
3079 Estne ebriamen de furfure avenaceo factum?
3080 Hostes aliengeni me abduxerunt. Qui annus est?
3081 Of course he [Jim Morrison] is dead and that is a high price to pay for immortality. -Gloria Estefan
3082 There's no such thing as a simple cache bug. - Rob Pike
3083 HELP! MY CAPS LOCK KEY IS STUCK DOWN, AND I CAN'T GET IT UP!
3084 The tree of research must be fed from time to time with the blood of bean-counters, for it is its natural manure. -Alan Kay
3085 The tree of liberty must be fed from time to time with the blood of patriots and of tyrants, for it is its natural manure. -Thomas Jefferson
3086 Unix broke upon the world as a refreshing breeze. -Doug McIlroy
3087 The specific heat of a solid slag is the weighted average of the specific heat of the constituent oxides. Westyn's Rule
3088 Two organic acids which are precipitated by the same base must have like configurations. Winther's Rule
3089 In an electrolyte, the product of the equivalent conductivity at infinite dilution and of the viscosity of the solvent is a constant. Walden's Rule
3090 The least solvated compound is most stable at high temperatures. Van't Hoff's Rule
3091 Higher temperature favors higher enthalpy; Higher pressure favors smaller volume. Van't Hoff's Rules
3092 The isomer with the higher dipole moment has the higher physical constants, regardless of the heat content. Van Arkel Rule
3093 $S sub m$ < 6.7 J/molK implies anomaly. Tiwari's Rule
3094 The erosion rate of a metal depends upon the melting point. Smeltzer's Rule
3095 If a slide is not readable when held at arm's length, it will not be readable when projected from the back of a conference hall. Slide Rule
3096 Impurities to the left of the host in the periodic table trap hydrogen; those to the right do not. Shirley-Hall Rule
3097 Phase boundaries, when produced, must extend into fields with a higher number of phases. Shreinemakers's Rule
3098 High K/G implies ductility; low K/G implies brittleness. Pugh's Rule
3099 A reagent will approach a ketone carbonyl group from the side with the smaller attached group. Prelog Rule
3100 In the anomalous Zeeman effect, lines of the same series exhibit the same pattern. Preston's Rule
3101 Oxide/metal volume ratios which are very different to unity imply poor oxidation resistance. Pilling-Bedworth Rule
3102 In diamagnetic organic compounds, the molar magnetic susceptibility is an additive property. Pascal's Rule
3103 Like functional groups in like surroundings make like contributions to the optical rotation.
3104 The boiling point of an organic isomer is proportional to the density of the liquid at the boiling point. Montgomery's Rule
3105 Other factors being equal, the metal which is most susceptible to failure is that with the lowest boiling point. Mogro-Campero Rule
3106 The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule
3107 In dipole radiation, only transitions between terms of opposite parity are allowed. Laporte's Rule
3108 Equal differences in the chemical composition of organic compounds give equal changes in boiling point. Kopp's Rule
3109 Avoid point loads. Areal loading is best, followed by line loading. Katz Rule
3110 Avoid stress concentrators. Maintain structural compliance. Katz Rule
3111 Minimize the severity of impact. Katz Rule
3112 Keep components as small as possible. Katz Rule
3113 Machine components very carefully. Katz Rule
3114 Factors which cause a marked decrease in the liquidus slope have a greater relative effect on the solidus slope. Hume-Rothery Rule
3115 Electricity travels one foot in a nanosecond. Hopper's Rule
3116 Atoms of even atomic number are more abundant in the universe than are atoms of odd atomic number. Harkin's Rule
3117 The sum of the g-factors is the same for strong and weak magnetic fields, for a given value of M. g-Permanence Rule (Pauli)
3118 The solid particle erosion rate of annealed face-centered cubic metals is inversely related to their hardness. Finnie-Wolak-Kabil Rule
3119 Metals mix with insulators if the reaction enthalpy is negative, and not if it is positive. Enthalpy of Mixing Rule
3120 One quantum of absorbed radiation activates only one molecule. Einstein Rule
3121 The ratio of the temperatures at which the vapor pressures of two similar substances are the same is a constant. Dång Rule
3122 Elements with high melting points have low coefficients of thermal expansion. Carnelly's Rule
3123 Reactions of Diels-Alder type with cyclopentadiene give cyclanes with a methylene bridge across a cyclohexane ring. Bredt Rule
3124 There is a clear relationship between the elastic modulus and the resistance to erosion. Brauer-Kriegel Rule
3125 The H atoms in ice lie on lines connecting the O atoms. Ice Rule
3126 There is only one H atom between any given pair of O atoms. Ice Rule
3127 Each O atom has two H atoms close to it and the unit of the water molecule is preserved. Ice Rule
3128 For any type of thing, there are more small things in the world than large things. Benford's Rule
3129 Carcinogenicity in polycyclic aromatic hydrocarbons is associated with the presence of a bay region. Bay Rule
3130 In order to obtain equations which reproduce a fractal object, tile the object with smaller copies of itself. Barnsley's Rule
3131 In dichroic crystals, the faster ray is less absorbed. Babinet Rule
3132 To calculate the slope of the best straight line through a set of points, join the first and last points. Bancroft's Rule
3133 The rate of a chemical reaction approximately doubles with each 10° rise in temperature. Arrhenius Rule
3134 In general, cis compounds have a higher density and higher refractive index than do the trans isomerides. Auwers-Skita Rule
3135 The sum of the maximum positive valency exhibited by an element and of its maximum negative valency is 8. Abegg's Rule
3136 A substituted biphenyl can be resolved if and only if the sum of the hanging bond lengths is greater than 0.29nm. Adam's Rule
3137 You know how when you're a virgin you wanna try everything and do it right? -nls
3138 Some time between 1991 and 1992 computers will start to kill human beings in a way that will be noticed. John Cullyer, head of RSRE.
3139 NOTE..NO WEATHER WILL BE AVAILABLE NEXT WEEK, JULY 22 THROUGH THE 26TH.
3140 Outside of a dog, a book is man's best friend. Inside of a dog, it's too dark to read. -- Groucho Marx
3141 And then there is of course the assumption that the disc is not made of beef and tossed with a hungry dog standing nearby. -Lambert Meertens
3142 int three = 128+64, two = 128, one=64;
3143 Help Run Uninsured Motorists Off the Road -- Ohio registration renewal form
3144 If you can't stand the heat, get a pool.
3145 If you can't stand the heat, get out of the oven.
3146 A bird in the hand is messy.
3147 Don't count your chickens, eat them.
3148 You can't teach an old dog new math.
3149 When in Rome, do Roman numerals in math.
3150 When in Rome, do bulls run around town?
3151 Too many cooks, so little meals.
3152 A fool and his money are my best friends.
3153 A penny saved is one cent.
3154 Look before you run into a pole.
3155 A watched pot never disappears.
3156 A rolling stone makes you flat.
3157 A rolling stone is a singing rock group.
3158 Every cloud has a wet spot.
3159 You take a banana, you get a lunar landscape. -J. van Wijk
3160 "Buffalo never Oink" -- a South Dakota travel brocure.
3161 Ken is very smart but also very opinionated. -- Doug Gwyn
3162 Anthony Burgess reports a friend's rendezvous with the ideal mannequin, all legs and no breasts. It was like going to bed with a bicycle.
3163 Narcissists receive callers without opening the door.
3164 If Bell Labs is a tree, research is a blossom, development is the fruit.
3165 You have to be careful not to get locked into Open Systems.
3166 It is likely that 2^104 is an ultimate limit on storage space, unless we want to turn New Jersy into a DRAM. -chuck@pierre.mit.edu
3167 Any worm measuring bigger than 2 metres is a big worm. - sign in Gippsland Giant Worm Museum
3168 Our first 'smoke' test showed that it is possible to hear Bob Marley and The Wailers through three feet of concrete.
3169 UX:mail: INFO: No mail.
3170 There is a need to keep from being locked into Open Systems. --IBM sales rep
3171 I'm giving the demo so why don't you just shut up? -rob (to ast)
3172 /* I APOLOGIZE FOR THIS CRAPY CODE -- presotto */
3173 X Moul - Ovum
3174 Testing is for bunglers. Properly designed mechanisms work properly. -E.E. Smith (Skylark 3)
3175 The Democrats just stand for `I want to be a Republican,' and the Republicans stand for raw evil. -Frank Zappa
3176 lp on plan 9 is fixed. -pg
3177 no more than 1 lp fortune per day -- rob
3178 The overhead involved in using a computer system is high enough that few people routinely use more than one. -Mike Lesk, 1980
3179 I think we should tread very carefully on governments that are constitutionally elected. - George Bush
3180 This is my prediction for the future: whatever hasn't happened will happen, and no-one will be safe from it. -JBS Haldane
3181 I have lived in a few cities: Nairobi, Edinburgh, Bradford, London, Sydney, New York. Washington is much nicer than Nairobi. - Piers Lauder
3182 Real software has its own 800 support line. Stu Feldman
3183 Communism must be like one big phone company. Lenny Bruce
3184 HONK IF YOU'RE ENTHUSIASTIC
3185 Don't the days seem lank and long when doughnuts don't come in.
3186 Eadum sunt, quorum unum potest substitui alteri salva veritate. -Leibniz
3187 It's like sticking your hands in someone else's pants: it just doesn't feel right. NP Nelson
3188 Military intelligence can be a contradiction in terms.
3189 Recoilless rifles - aren't.
3190 A sucking chest wound is nature's way of telling you to slow down.
3191 The enemy diversion you are ignoring is the main attack.
3192 If the enemy is within range, then so are you.
3193 Professionals are predictable, but the world is full of dangerous amateurs.
3194 Killing for peace is like whoring for virginity.
3195 Marine math: 2 beers times 39 Marines is 49 cases.
3196 Body Count Math: 2 VC plus 1 chicken and 3 pigs equals 37 enemy killed in action.
3197 Low expectations are the key to happiness. - Pamela Zave
3198 Sometimes I think the surest sign that intelligent life exists elsewhere in the Universe is that none of it has tried to contact us. -Calvin
3199 20 octets is 160 guys playing flutes -- rob
3200 chan[2]='m'; /* Ooh, careful! */
3201 Many system design flaws can be traced to unwarrantedly anthropomorphizing the user.
3202 The common theme to all three of the A320 crashes is lack of altitude. -Aviation expert.
3203 Clear your screen after you log off.
3204 #define struct union /* Great space saver */
3205 Maybe there is no death as we know it. Just documents changing hands.
3206 It's the only avant-garde we got.
3207 When times are bad, people feel compelled to overeat.
3208 If you could become more ugly, it would help your career enormously.
3209 You have a vast capacity for becoming embarrassed on other people's behalf.
3210 You have important hair.
3211 We seem to believe it is possible to ward off death by following the rules of good grooming.
3212 I just hate to be pushed around by some @#$%^& machine. - Ken Thompson, on the i960
3213 Easy reading is damned hard writing. - Sheridan
3214 After hydrogen, the most common thing in the universe is stupidity. -Harlan Ellison
3215 MOVL R1,
3216 How can you write a big system without C++? -Paul Glick
3217 So, if you put a G on the front you have to put a zero on the back? -Ken
3218 As usual, please try to use a reusable mug.
3219 I'd use plan 9 before i'd use bitfields -- pjw
3220 Of the physical pages in use, 3436738592 pages are permanently allocated to VMS.
3221 February marks the fag end of Bombay's short mild winter spell.
3222 Let's share those threats
3223 Let's not beat ourselves up for being defensive
3224 There's some Jungian principles inside us
3225 There are many feedback loops into your system
3226 Time to take a stretch-break (possibly self-managed)
3227 There'll be massive chaos downstream
3228 Feel your own power
3229 We're getting lots of dysfunctional acting-out of anxiety
3230 We've got to raise this to a double-loop system
3231 We've got to keep upping the control until one of us goes nuke!
3232 The conflict has to be ritualised in order to get it addressed
3233 If you carry on, head-to-head, on `solution' you don't get anywhere
3234 That sort of `collusive carrying' just isn't on.
3235 Everybody will soon be owning their incompetence
3236 They'll be scapegoated because they have a valency for incompetence
3237 You gotta pump-prime your seed-corn
3238 You need a proactive planning horizon
3239 I want you to feel your own power
3240 Let's fix a frame on these issues and focus on the power dynamics in the room
3241 Infinite retry on parallel printer time-out
3242 A system is Unix if and only if it will compile and run everything on prep.ai.mit.edu without restrictions.
3243 Can you sum up plan 9 in layman's terms? It does everything Unix does only less reliably - Ken
3244 (hch:) Can't find /you/must/specify/HCDIR/bin/hc@sun41com
3245 There are tons of bad AD and DA convertors out there, but they don't make Nyquist wrong. -Marc LoCascio
3246 This is like ignoring both the speed limit and the odometer in your car. It won't get you far. -Kenneth P. Birman
3247 I didn't really expect to find elephants on the airport runway, and there weren't any. -dmr
3248 "Objective" and "subjective" are not entirely subjective. - Penn Jillette
3249 The alpha is doing a lot more computation than a lightbulb -- rob
3250 It is rarely wise to underestimate the taste of the truly pious.
3251 WAIS allows relevance feedback
3252 Once you start talking about Nothing, people think you're some sort of idiot. -John Cage
3253 Why is there only one Monopoly commission?
3254 If something could be done about cache misses, programs would run about twice as fast. -Andrew Appel
3255 mount: mount /srv/boot /n/bootes: permission denied
3256 Kudos to everyone on the WKSH Team!
3257 the application "unknown" has unexpectedly quit, because of sys.
3258 BUSINESS UNIT NEWS:
3259 o UNIX System Labs launches a torrent of announcements
3260 /bin/ls: exec header invalid
3261 If you wish to vote "No opinion" on any topic, you must cancel gut.wksh and execute gut instead.
3262 Huiswants es.
3263 Motto: Compute with fermions, communicate with bosons. -Vincent Heuring
3264 The flip side of change is trust. -George Bush
3265 We are changing the alignment, not the membership. -John Mayo
3266 The President [Bush] is just a guy who sucks in life. - White House aide
3267 At MIT the server is the unit of invention. -Rob Pike
3268 The dependency dag for a target consists of nodes connected by directed arcs.
3269 I was an asshole when you (philw) were still a gleam in your father's eye. -Bob Flandrena
3270 Beleidigungen, Beschwerden und Flames bitte an NUL schicken.
3271 Fashion, though a goddess, is a fool, and all her worshippers..are nincompoops. E. S. Barrett
3272 You advocate a lot of egg sucking but you're not very forthcoming with the eggs. Phil Winterbottom (to ken)
3273 My pile of equipment is bigger than your pile of equipment -- philw
3274 Mathematics is ... the hot and chaotic work of the devil. Quayle needn't know this. -Vaughan Pratt
3275 51HAren't you glad you don't have to do this anymore?
3276 Virtual caches are the worst idea since register windows. - Phil Winterbottom
3277 cetus news: Cannot open /usr/news/
3278 ``Ausserordentlich chaotisch, dissonant, und häßlich.'' -review of premiere of Beethoven's 9th
3279 Why is the text on my screen turning umop-apisdn?
3280 There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977
3281 coproc proto viol
3282 Time wounds all heels.
3283 Live fast, die young, leave a long publication list.
3284 150 Opening ASCII mode data connection for 9ss.Z.
3285 Maximum number of users exceeded - try again laterConnection closed by foreign host.
3286 Connected to 192.65.218.43.
3287 When in doubt, twirl. -Ted Shawn
3288 ¿Tôø müçh öf á gòód thìng?
3289 Writing about music is like dancing about architecture. -Frank Zappa
3290 Quando la neve si scioglie si vede la merda.
3291 I wonder how Plan 9 could be used to monitor shut-ins? -- L. Bernstein
3292 Semper ubi sub ubi.
3293 Lesson 10 - Who killed Bambi?
3294 Is it a lot of blokes with long hair and guitars around their necks? -Keith Richards (on Nirvana)
3295 Much may be made of a Scotchman, if he be caught young. - Samuel Johnson
3296 Memory tests terminated by keystroke
3297 Rome deserves you. - Tiberius to Caligula.
3298 as1: Error: ../bpvvv.c, line 1324: Too many float literals--compile with "-Wb,-nopool"
3299 } /* the next line is indented funny to preserve old indentation */
3300 syslog(LOG_WARNING,"/etc/copyright may be too large");
3301 Cab drivers are living proof that practice does not make perfect. - David Dinkins
3302 It's well we cannot hear the screams/That we create in others' dreams.
3303 At twilight, objects often start/To make odd sounds and fall apart.
3304 A random thought, if said aloud,/May soon attract a hostile crowd.
3305 A timely use of glue or paste/May well prevent a shocking waste.
3306 One cannot hope to end one's life/With nothing but a butter knife.
3307 The seaweed on the shore cries out/But only it knows what about.
3308 It's possible to pick up crumbs/By pressing on them with the thumbs.
3309 The one who wants to put on airs/Should not attempt them on the stairs.
3310 The person who today is here/May by tomorrow disappear.
3311 The helpful thought for which you look/Is written somewhere in a book.
3312 A one- or two-inch piece of string/Cannot be used for anything.
3313 Upon your person keep a pill/In case you're taken deathly ill.
3314 Britain has football hooligans, Germany has neo-Nazis, and France has farmers. -The Times
3315 Government Warning: According to the Surgeon General you're going to die.
3316 Perscriptio in manibus tabellariorum est.
3317 Please do not urinate in the rain gauge. - sign on Mt. Kilimanjaro
3318 Nothing is worth spending a week with bureaucratic Germans. -rob
3319 The implementation should provide some reasonable value (80? 255? 509?) rather than something unusable like USHRT_MAX. - ANSI C Rationale
3320 Real data are normal in the middle and Cauchy in the tails.
3321 accom: Warning 310: restart.c, line 148: A file with no declarations or definitions is accepted as an extension to ANSI C
3322 Always go for overkill. -Lou Reed
3323 Available only for MEI designed 3.5"MO series. Do not use it absolutely in another drive.
3324 Is the tool broadly supported or maintained?
3325 You don't need rain in a movie, and you don't need ``paradigm'' in a book. - Penn Jillette
3326 Routine work drives out creative work - Arno Penzias
3327 If my career depended on dot-dot, I'd be on the dole. - philw
3328 >>>'/€€ ܇€€D/€' panic: decref
3329 150 years ago everybody was a Christian Scientist. dmr
3330 Featuring the Intel 14.4EX with V.42bis and MNP5
3331 Look what David Koresh did, rather than go home and visit HIS parents! - Teller's mother
3332 It appears that people would rather have their hands on the wheel and drive off the cliff than be thrown over naked. (scj in Computing Systems)
3333 'Gigabit' seems to mean 600 megabits. It's a VAX gigabit. - ken
3334 Valid license for the following required when not using dbx on kernel. Product OSF-DEV (OSF Developer's Kit): No license found.
3335 Life is hard. It's even harder if you're stupid.
3336 I'm pulling *something* here. - Dom Marotta
3337 From: No gas will be sold to anyone in a glass container <SKASS@DREW.DREW.EDU>
3338 Figure 1b shows how C++'s pure virtual functions turned a black box into a toroidal design
3339 (accom): tasks.c, line 7576: accom: Internal: Out of tree space. Cannot continue compilation. The current size was specified as or defaulted to -Wf,-XNh1000 giving a table size of 1000. Recompile giving a command line option to increase the table size. Example option giving a larger table: -Wf,-XNh2000
3340 No UNIX system on the market supports more standards than DEC OSF/1.
3341 I despise the little old ladies of both sexes. -Charles Ives
3342 What does sound have to do with music? -Charles Ives
3343 YOU are welecome to Cheboxary!!
3344 I don't need any help, 'cause I'm not doing anything. -Howard
3345 ugen: warning : line 979 : ../../../../../../src/usr/ccs/bin/ugen/const_idiv.p, line 230
3346 VAX portability is assured.
3347 Additionally, the paper [xxx] can serve as an excellent tool to help any new project introspect about how it will do business. - Jim Coplien
3348 We are not wholly an island, except geographically. - John Major
3349 I'm drawing a line under the sand. - John Major
3350 Always wear underpants beneath your kanzu before you mount your bicycle.
3351 Humiliation is intrinsically comic. - Frank Conroy
3352 C gains much of its vaunted efficiency by employing a very powerful pre-processor, usually called a ``programmer''.
3353 T-shirt: Mom and Dad invented OOP in the 70's and all I got was C++
3354 DEC OSF/1 V1.2 Worksystem Software (Rev. 10) The installation software has successfully installed your system.
3355 BD-445G (red compact car) lights no longer on
3356 Checking system endianess... Big endian
3357 Subject: ** PROCESS CHANGE ALERT ********************** ERROR:(-)input line 8:LI:no lists active Distribution: ihlpb!pca-usi5e
3358 If Dennis Ritchie were the man who developed Modula-2 then C would be long forgotten. -Tarjei Jensen
3359 From --rw-rw-rw- Sun Aug 15 04:21:17 EDT 1993
3360 If you're smart you'll remain ignorant - bobf
3361 They bit the wrong chicken's head off with their own teeth and got blood all over their shirt - nls
3362 Everybody gets so much information all day long that they lose their common sense. -Gertrude Stein
3363 A coach is someone who lives and behaves Our Common Bond, and views each coaching interaction as a real measure of truth.
3364 Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave
3365 Standards is an area that is constantly changing. -Carl Cargill (ed. ACM StandardView)
3366 This will be sexy: nothing like a good tty driver to turn you on. - Phil Winterbottom
3367 To find out a person's userid, ask him. --IBM VM/CMS Primer
3368 Blessed be the optionless, for they shall not eat gnu
3369 Every old barn can use a little paint. - Tammy Faye Bakker on Primetime Live 11/18/93
3370 The sendmail security patch will be available in approximately two weeks.
3371 Diversity better than intensity -- Xerox PARC talk (conclusion)
3372 Sir Francis Drake circumcised the globe with a hundred foot clipper.
3373 If a train station is where a train stops, what's a workstation?
3374 I just want a bare-boned, straight EMACS. - Rae McLellan
3375 Cohesion and coupling are intertwined.
3376 SPEC results inflated by too many compiler flags. -Microprocessor Review
3377 a.out: does not have gp tables for all it's sections
3378 ?warning: write might change good version of `sendmail'
3379 Being afraid of X is about as sensible as being afraid of sendmail.
3380 I wish these damn scientists would leave intelligence to the experts. -Gen. Richard Stillwell (CIA)
3381 #include... <depending on your compiler>
3382 I don't like to spend my time on sterile discussions -- Bjarne Stroustrup, in The Evolution of C++
3383 There is no problem so simple that management can fix it. - Dave Presotto
3384 Fat Triangles Determine Linearly Many Holes
3385 We send our young men to fight wars. Ants, at least, send their old women. - E.O. Wilson
3386 #/->/ := #/->/
3387 *** Message content is not printable: delete, write or save it to a file ***
3388 It's a tiny change to the code and not completely disgusting. - Bob Manchek
3389 I want to die peacefully in my sleep like my grandfather, not screaming in terror like his passengers. --Charlie Hall
3390 emacs: Terminal type "emacs" is not powerful enough to run Emacs.
3391 xterm: Error 50, errno 1: Too big
3392 RMS was neither ignorant nor lying. He simply used word choices that created confusion.
3393 User Needs Drive IS To Wherehouse -- OS Today headline
3394 Probably not a complicated question - how does the mount driver work? - C.R. Kalmanek
3395 Subject: no subject (file transmission)
3396 If you find any unidentified object under your seat, please do not attempt to smoke it.
3397 ML is a language for people with excess IQ points. - John Ousterhout
3398 The Big Bang theory: In the beginning there was nothing, which exploded.
3399 Someone's searching for sex in the 800 database.
3400 1181258 SAVECORE SEGMENTATION FAULT WHILE TRYING TO SAVE CORE
3401 Middleware is the implementation of a concept. - Ed Szurkowski
3402 FOUND IN SUPPOSEDLY EMPTY EQUIPMENT, MATTOON, IL POST OFFICE 61938
3403 To back up the 57th platter in the file system type 'wormingest 49; wormcp 62 49'.
3404 /n/a:/100377-15/sun3/4.1.1/sendmail: Ascii & Extended Latin & Cyrillic & Hebrew text
3405 Not responsible for errors in typo.
3406 This is AT&T. Communication is our business, not our mode of working. - Jim Clemans
3407 How much clearer everything is when you underline! - Ron Hardin
3408 Improve our mechanisms for sharing BU and "white space" opportunities knowledge and laboratory and center capabilities so as to assure optimal use of contrained resources.
3409 The Internet grows hyperbolically, but is usually described elliptically. - Dr. Internet
3410 Microsoft - We put the "backwards" into backwards compatibility.
3411 Many will urinate with joy in having shared in the hacking of your neck. - a comment on netnews
3412 [Acting] was a lot more difficult than modeling. There's a lot to remember. -Cindy Crawford
3413 Everything that can ever be invented has been invented -Charles H. Duell, Commisioner of U.S. Patents, 1899.
3414 The complex-type shall be a simple-type. ISO 10206:1991 (Extended Pascal)
3415 The "do one thing well" philosophy underlying UNIX is best realized in a fully object-oriented environment. - some Linux guy
3416 Subject: slip:UX:killall: INFO: killing pid 140 <routed>
3417 There are only two industries that refer to their customers as "users". - Edward Tufte
3418 I think you have to really be an engineer to run a technology company. - Bill Gates
3419 hd2: model oCnnreP repieharsl6 with default 1471 cyl 5 head 17 sec
3420 I want to make sure everybody who has a job wants a job - George Bush, during his first Presidential campaign
3421 This is a great day for France! - Richard Nixon, while attending Charles De Gaulle's funeral
3422 I believe we are on an irreversible trend toward more freedom and democracy. But that could change. - Dan Quayle
3423 What a waste it is to lose one's mind-or not to have a mind. How true that is. - Dan Quayle addressing the United Negro College Fund
3424 The caribou love it. They rub against it and they have babies. There are more caribou in Alaska than you can shake a stick at. - George Bush, on the Alaska pipeline
3425 I hope I stand for anti-bigotry, anti-Semitism, anti-racism. This is what drives me. - George Bush
3426 Mondale: George Bush doesn't have the manhood to apologize. Bush: Well, on the manhood thing, I'll put mine up against his any time.
3427 #define n_zeroes _n._n_n._n_zeroes
3428 To me, boxing is like a ballet, except there's no music, no choreography and the dancers hit each other.
3429 Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.
3430 Sorry, the passowrd you asked for is too long. Please choose a password that is 2147459392 to 8 characters long.
3431 Television is a medium. So called because it is neither rare, nor well done. -- Ernie Kovacs
3432 The last good thing written in C was Franz Schubert's Symphony No. 9.
3433 This is the best recruiting season we've ever had. - Ken Thompson, Dec 21, 1995
3434 Don't anthropomorphize computers - they hate that!
3435 Press Ctlt-Ds Ctlt-Del a to reboour reboour mach
3436 cfe: Warning 712: irix.c, line 311: illegal combination of pointer and integer .... ? ( (((long)*arg & 0x1) ?(*arg = (char *)((long)*arg + 7),(char *)((long)*arg-6-_VA_FP_SAVE_AREA)) :(((long)*arg & 0x2) ?(*arg = (char *)((long)*arg +10),(char *)((long)*arg-24-_VA_FP_SAVE_AREA)) :( ((*arg)=(char *)(((unsigned int)(((char *)*arg)+((__builtin_alignof( long))>4?(__builtin_alignof( long)):4)-1)) & -((__builtin_alignof( long))>4?(__builtin_alignof( long)):4)) + (((unsigned int)(((char *)sizeof( long))+((4)>4?(4):4)-1)) & -((4)>4?(4):4)) ), (((char *)*arg) - ((((unsigned int)(((char *)sizeof( long))+((4)>4?(4):4)-1)) & -((4)>4?(4):4)) - sizeof( long))) ) ))) : ( ((*arg)=(char *)(((unsigned int)(((char *)*arg)+((__builtin_alignof( long))>4?(__builtin_alignof( long)):4)-1)) & -((__builtin_alignof( long))>4?(__builtin_alignof( long)):4)) + (((unsigned int)(((char *)sizeof( long))+((4)>4?(4):4)-1)) & -((4)>4?(4):4)) ), (((char *)*arg) - ((((unsigned int)(((char *)sizeof( long))+((4)>4?(4):4)-1)) & -((4)>4?(4):4)) - sizeof( long))) ) )))[-1] );
3437 Here in Nuremberg, information hiding is much more popular in the organization than it is in the software...
3438 yes >/dev/kmem # Shutdown is broken. This'll have to do
3439 "No one steals our chicks," sneers Duke, "and lives."
3440 You must engineer for the technology curve and set the intercepts to match the emerging business markets. - Phil Winterbottom
3441 Wovon man nicht sprechen kann, darüber muß mann schweigen.
3442 When your hammer is C++, everything begins to look like a thumb. -- Steve Hoflich, compl.lang.c++
3443 This is SGI Bug #375613.
3444 If mamma ain't happy, ain't nobody happy.
3445 error code 4A: Could not free fingers from storage slot after insert
3446 At Microsoft, quality is job 1.1.
3447 You are thehttp://counter.digits.com/wc/-d/4/cpluscounter visitor since May 1, 1996
3448 It's hard to compete with conventional cukes.
3449 PEALSE CAN YOU ADIVE ME WHAT TO DO :)
3450 License Error : The license for this product(SPARCompiler C) has expired
3451 ARMY FOCUSES ON SECOND BASE IN SEX PROBE
3452 In Pursuit of Software Excellence: If you want to become a leader, follow the leaders.
3453 Thank you for sending me a copy of your book. I'll waste no time reading it. - Moses Hadas
3454 In label expressions, <> expressions are ignored inside .char expressions.
3455 I have made this letter longer than usual, because I lack the time to make it short. Blaise Pascal in: Lettres Provinciales, #4, Dec 14, 1665
3456 If I had more time, I should have written you a shorter letter. Mdm. de Staël (1766-1817)
3457 UNIX geek since 486651600
3458 Speed is more important than anything else in management. - Henry Schacht
3459 No proper program contains an indication which as an operator-applied occurrence identifies an operator-defining occurrence which as an indication-applied occurrence identifies an indication-defining occurrence different from the one identified by the given indication as an indication-applied occurrence. - Algol 68 Report
3460 Cwm fjord bank glyphs vex't quiz.
3461 Outside of the killings, Washington has one of the lowest crime rates in the country. -- Mayor Marion Barry, Washington
3462 Clearspeak also is a euphemism for what advertising people call the "dominant brand" or "masterbrand" approach. - Bell Labs News, April 1, 1997 (but not April Fool's)
3463 My favorite thing about the Internet is that you get to go into the private world of real creeps without having to smell them. - Penn Jillette
3464 Note: gtest.java uses a deprecated API. Recompile with "-deprecation" for details.
3465 Malcolm [grandson of Malcolm X] walked into court yesterday afternoon to face charges of juvenile delinquency, mumbling and hiding his head under a red plaid blanket. - N. Y. Times
3466 Usenet is like letters to the editor, only without an editor. - Larry Wall
3467 Who are you going to believe? Me or that lying sheep? -- Jim McKie
3468 Line 3 of "/usr/add-on/trouble/bin/trouble": syntax error; saw '<'. Undefined: "Main"
3469 I don't think you can really know how heavy something is until it has fallen on you. --LeMel Hebert-Williams
3470 I don't think so, therefore I'm probably not. --Alan Smithee
3471 Are you sure you want to send 'Pleonasm' to the recycle bin?
3472 The days of the digital watch are numbered. -Tom Stoppard
3473 ^Eds: SUBS 3rd graf, `So what's ...' to remove accent from 'derriere.'
3474 WELL YOU MISSED IT. I WAS ON THE RADIO AND WAS IN A CONTEST TO WIN FLEETWOOD MAC TICKETS. I WAS MCNICKOLS. I WORE A TUTU AND POURED 2 GAL. OF HERSHY CHOC. OVER MY HEAD. I GOT 2ND A GIRL IN A TEDDY EATING DOG FOOD AND BARKING WON. MALE JUDGES GO FIGURE (IT WAS SEE THROUGH)
3475 <A HREF="http://images.nytimes.com/RealMedia/ads/click_lx.ads/www.nytimes.com/index.html/0/Left/attbmd011/att4-head.gif/63636232316630323334393032316530" target="_top"><IMG SRC="http://images.nytimes.com/RealMedia/ads/adstream_lx.ads/www.nytimes.com/index.html/0/Left/attbmd011/att4-head.gif/63636232316630323334393032316530" border=0 WIDTH=468 HEIGHT=60 ALT="Just add AT&T" ></A>
3476 It's a very good idea to compare apples and oranges, that's a big part of what thinking is about. - Penn Jillette
3477 Your glasses will include miniature video cameras that will give you a stereo vision of your environment. -- Arno Penzias
3478 Music is the pleasure the human soul experiences from counting without being aware that it is counting. -Leibnitz
3479 ^Bearded lady, friend killed in possible case of mistaken identity<
3480 I think I'm getting mellow in my old age. - Phil Winterbottom
3481 Cu' si marita sta contentu 'nu giornu, cu' ammazza 'u porco sta contentu n'annu
3482 How can they identify me? I had a mask on. - Weird News criminal
3483 If it has more than three chords, it's Jazz. - Lou Reed
3484 If there were a god, we'd be able to walk upright without back problems. -Penn Jillette
3485 Birds are entangled by their feet and men by their tongues.
3486 No viewpoints are banned. Except those banned by the law. -- Iranian President Mohammed Khatami
3487 uopt: Warning: insert_aux__91deque__pt__78_21basic_string__pt__2_c45__default_alloc_template__pt__13_XCiL11XCiL10XCUiL10F103__deque_iterator__pt__79_21basic_string__pt__2_cR21basic_string__pt__2_cP21basic_string__pt__2_cXCUiL10105__deque_iterator__pt__81_ exceeds size threshold; to optimize this procedure, use -Olimit option with value >= 1217.
3488 "shaneystl.c", line 24: Note: Type "CC -migration" for more on anachronisms.
3489 The Lucent Real Estate Strategic Intent: "One ignited team, unleashing productivity through bold work place solutions and unforgettable service."
3490 This program cannot be run in DOS mode.
3491 Your mouse has moved. Windows NT must be restarted for the change to take effect. Reboot now?
3492 Millenium parties/with loud music, lights and joy;/then, how cold!
3493 Stupid programmer,/think ahead next time, when the/power's back.
3494 Windows 98 is/compliant with minor bugs,/store water!
3495 Hire more programmers/for Y2k Bug now -- Oops,/lights are out!
3496 Y2k is just/a scam for consultants -- hey/Martial law!
3497 Two digits lost,/the railroad switch spills coal --/scavengers!
3498 UX:cancel: WARNING: Request "SPARCprinterII-64" is done. TO FIX: It is too late to do anything with it.
3499 If you give a man a fire, he'll be warm for a day. If you set a man on fire, he'll be warm for the rest of his life.
3500 We don't write assembly language, we steal it. - brucee
3501 The Elements of Style is as much as guide to success as it is to grammer. - Reader on amazon.com
3502 Simon says, ``Don't be so suggestible.''
3503 The IAU reports that RX Pup has returned to a state of high excitation and has had a mass-ejection event.
3504 JAVA truly is the great equalizing software. It has reduced all computers to mediocrity and buggyness. - NASA's J-Track web site
3505 warning: Hit heuristic-fence-post without finding enclosing function for address 0xfa2e470
3506 You're just a hologram - I outrank you.
3507 Mechanically Separated Chicken. - Ingredient label
3508 You have mail.™
3509 Stare at the thumbnails closely to view larger images.
3510 This is a ruggedized telephone, it does everything a normal telephone does, but ruggedly. - Al Gore
3511 All along the untrodden paths of the future, I can see the footprints of an unseen hand. Sir Boyle Roche, MP
3512 There's really no way to fix this, and still keep Perl pathologically eclectic.
3513 Welcome to Netscape Quality Feedback Agent - Step 1 of 3
3514 FOR FASTER SERVICE, PLEASE CALL US WITH YOUR REFILLS 24 HOURS IN ADVANCE
3515 Anthrax is cool. - Tad Hunt
3516 (never claims generated from LTL formulae are stutter-closed)
3517 /text/plain00charsetUTF-80 you stuff by snail,
3518 War in the Clinton era is just P.R. by other means. - Michael Hirschorn
3519 If I can see a bit further it is because I stand on the shoulders of Hungarians. - Mathematician Paul Winkler
3520 I don't want any yes-men around me. I want everybody to tell me the truth even if it costs them their jobs. - Sam Goldwyn
3521 We do not need phones, we have a lot of messenger boys - British Scientist in 1876
3522 I did write and prove correct a 20-line program in January, but I made the mistake of testing it on our VAX and it had an error, which two weeks of searching didn't uncover, so there went one publication out the window. - David Gries, 1980
3523 It's not whether you win or lose; it's where you place the blame.
3524 ISDN: PPP-Daemon funktioniert nicht mehr
3525 Hey medalist, don't forget to take out the recycling. -- Bonnie Thompson
3526 There are three kinds of people - those who can count, and those who can't.
3527 You buy 'em books and you buy 'em books and they just chew on the covers.
3528 I wouldn't give your troubles to a monkey on a rock.
3529 This should only be a momentary outage, of about 10 minutes or so.
3530 The ignored registers are for future backward-compatible extensions. - IA-64 Application Developer's Architecture Guide
3531 /lib/shakespeare/sonnets: limbo program
3532 Does the additional overhead of doing a function call make this act less atomic? -- pip
3533 A cockroach will live nine days without its head, before it starves to death.
3534 Are you proposing a solution or just whining? - Dave to Dave
3535 Nothing says "happy father's day" quite like the flesh-stripped skull of a moderate sized rodent. - Corey Thompson
3536 You are running the GNOME File Manager as root. As root, you can damage your system, and the File Manager will not stop you.
3537 A document with the name `junk.xls' is already open. You cannot open two documents with the same name, even if the documents are in different folders. To open the second document, either close the document that's currently open, or rename one of the documents. - Microsoft Excel
3538 When your output is negligible, losing a day's work is insignificant. -- presotto to rsc
3539 Expensive solutions to all kinds of problems are often signs of mediocrity. - Ingvar Kamprad, founder of IKEA
3540 Ches is the Dennis Rodman of science. -Cliff Young
3541 if your terminal stops booting, I'll be in the unix room.
3542 ! TeX capacity exceeded, sorry [main memory size=263001].
3543 The system suspend request has been rejected. To conserve power, shut down the computer. - NEC Versa LX
3544 If you don't find it in the index, look very carefully through the entire catalogue. - Sears & Roebuck catalogue, 1897.
3545 This program is protected by US and international copyright laws as described in the About box.
3546 Lucent in Motion is almost in full swing.
3547 pi + onions = opinions
3548 If there was [sic] a single standard for the English language it would not be necessary to support redundant spellings. - OSF1 ls(1) man page
3549 Set an example for your kids by learning to read and write.
3550 21st Century Cyborg Returns To Kill Waitress.
3551 I'm smiling on the outside and beating you senseless on the inside. You creep! -- S.P. Eills
3552 You will set the register! To the correct value!
3553 Anti-Virus Software Users: Some anti-virus software programs may interfere with the download and should be disabled while installing the Microsoft software.
3554 You gotta think of fear as a tool. - Phil Winterbottom
3555 His hand was bitten by his own side in an offhand way. - Mark V. Shaney
3556 The more things change, the more he loves the flag. - Mark V. Shaney
3557 Don't meddle in the mouth. - Mark V. Shaney
3558 Will the call be routed on the same switch or will it go out over a truck to another switch?
3559 I may be a bad woman, but I'm awfully good company. - Fanny Brice
3560 apmd[105]: On-line: * * * (100% unknown)
3561 P.P.S. Thanks for helping make BUY.COM the #l online computer retailer.
3562 I hope some animal never bores a hole in my head and lays its eggs in my brain, because later you might think you're having a good idea but it's just eggs hatching. - Jack Handey
3563 I only lie to the ones I don't like, the ones who ask stupid questions.
3564 The proofs of the associative, commutative, and distributive laws for the integers are exercises in induction which might be called ``Peano playing.'' - An algebra textbook
3565 The observation could be "a real break-through" in osteoporosis treatment. - Science magazine
3566 Life is very strange - compared to what? - Penn Jillette
3567 Your search for difficentralia returned 0 article(s). If this is too many articles you may want to narrow your search. - www.nytimes.com
3568 Sperm bank sued for tossing samples - Headline in Star-Ledger
3569 Spell check: did you mean unicorde? - altavista
3570 The Linux, and in particular the Free Software, movement, if not the mark of technological progress, is the sign of social progress. - muzzetta@videobank.it, in 9fans.
3571 I do hope not to live long enough to see the launch of Quantum Windows. --Artur Ekert
3572 In science, we give our highest award to people that prove us wrong. -- Michael Goudeau
3573 Indian Hill is like the Borg. -- Phil Winterbottom
3574 My sister married a German. He complained he couldn't get a good bagel back home. I said: 'Well, whose fault is that?' - Emo Philips
3575 --rwxr-xr-x M 9501 geoff geoff 1417216 Dec 30 14:16 .
3576 log10: SING error -- borland c/c++ 3.1
3577 You have the power to write your own fortune.
3578 .NOTICE; ;?This comment is definitely out of date
3579 If at first you don't succeed, sky-diving is not for you.
3580 boot: nop...cfs...session...no physical memory
3581 doofus is God-like
3582 The quantity specified for 3Com Palm Vx is too great. We only have -1 available. - some e-commerce site.
3583 Man-animals cannot fly!
3584 Software is the stuff that never works, always has to be maintained, and hardware is the other stuff. - Arno Penzias
3585 Money, sex, storage, and bandwidth -- these are the things where too much is enough. - Arno Penzias
3586 linux-2.3.99-pre9.tar: limbo program
3587 temp &= 0x07FFFBFB; // clear bits 31 and 30
3588 An error has prevented <%=ServiceName%> from locating the message.
3589 8.out 723: warning: process exceeds 2100 file descriptors
3590 A dirty mind is a perpetual solace. - Air Commodore Sir Charles Kingsford Smith
3591 Vulcan Proverb: Only Nixon could go to China
3592 Why I have to write echo "reboot" > reboot ? I prefer to write this.reboot = reboot - <alter@cybercafe.com.ua> (Alt)
3593 There's method in the key of C.
3594 Computers come in putty-colored boxes and have AUTOEXEC.BAT files and run screen-savers with flying toasters, and brains do not. - Steven Pinker
3595 Your mail regarding "" will be read when I return.
3596 Esperanto, why don't you come to your tenses.
3597 That's why it's distributed. So it's always wrong somewhere.
3598 BT,DT,fixed quite a few of them. - Al "-15kLOC during the last year" Viro
3599 Please wait while Microsoft Outlook exits.
3600 First off, I'd suggest printing out a copy of the GNU coding standards, and NOT read it. Burn them, it's a great symbolic gesture. - Linus Torvalds
3601 Kitchen: Selecting Blendolini Causes Choco-Banana Shake Hang
3602 I hope I can finish the garbage collector before I run out of ice. - brucee
3603 This recipe [for toad in the hole] will stand or fall by the quality of your sausages. - Fanny Farmer
3604 The machine FROG was re-named MESSIAH.
3605 Your coat becomes like a car with the stereo playing and the car phone ringing.
3606 Invalid null command.
3607 We have discovered a pervasive nonstationarity.
3608 No that's your chair. Mine has the drum machine on it. - Tad
3609 Not mistakes - highly co-ordinated mistake opportunity initiatives.
3610 If your neck is as wide as your head ... take the day off.
3611 She will have SME (subject matter experts) from her organization call you ...
3612 Man who stand on toilet ... high on pot.
3613 If your article contains quoted text please take some time to pare it down to just the key points to which you are responding, or people will think you are a dweeb! -a unix news reader
3614 The name "grep" comes from the vi editor. - An undergraduate computer science course
3615 gcc -Isomenonstandardplace -Dverylongoption -Wpleasedontcomplainaboutmyprogramiknowhatimdoing ilikethingstobeclearsoigivemyfileslongnames.c
3616 You are a nuclear menace. Your warhead should be dismantled.
3617 A zone contains the domain names that the domain within the same domain name contains, except for domain names in delegated subdomains.
3618 Subject: [9fans] Re: =?iso-8859-1?Q?=5B9fans=5D_R=E9f=2E_:_=5B9fans=5D_Sun_has_a_Plan_9_inspi?=\n =?iso-8859-1?Q?red_project_called_=22Brazil=22!!=3F=3F=3F?=
3619 //******************************************* A L I G N M E N T **********************************************
3620 ntimesync.c:666 external redeclaration of: whatisthefrequencykenneth
3621 It is my carefully considered opinion that C++ represents an additional hazard to the survival of a project. - Alistair Cockburn
3622 verb = a > b ? 'a': c > d ? 'd': 'c';
3623 pwd: window deleted
3624 Your personality is your greatest invention.
3625 I'd rather make love amongst the flowers than take lots of cold showers.
3626 There is not enough memory to load all your extensions.
3627 VbeSignature should be set to 'VBE2' when function is called to indicate VBE3.0 information is desired.
3628 Zoinks! Jimminy-jillikers, B-man, that is strange! =)
3629 A great deal of agonizing and very little decisiveness went into resolving this issue -- Rob Pike
3630 /opt/gcc-2.95.2-irix6.2-o32/lib/gcc-lib/mips-sgi-irix5.3/2.95.2/cpp -lang-c -v -I. -D__GNUC__=2 -D__GNUC_MINOR__=95 -Dunix -Dmips -Dsgi -Dhost_mips -DMIPSEB -D_MIPSEB -DSYSTYPE_SVR4 -D_SVR4_SOURCE -D_MODERN_C -D__DSO__ -D_MIPS_SIM=_MIPS_SIM_ABI32 -D_MIPS_SZPTR=32 -D__unix__ -D__mips__ -D__sgi__ -D__host_mips__ -D__MIPSEB__ -D_MIPSEB -D__SYSTYPE_SVR4__ -D_SVR4_SOURCE -D_MODERN_C -D__DSO__ -D_MIPS_SIM=_MIPS_SIM_ABI32 -D_MIPS_SZPTR=32 -D__unix -D__mips -D__sgi -D__host_mips -D__MIPSEB -D__SYSTYPE_SVR4 -Asystem(unix) -Asystem(svr4) -Acpu(mips) -Amachine(sgi) -D__CHAR_UNSIGNED__ -g -Wall -pedantic -D__LANGUAGE_C -D_LANGUAGE_C -DLANGUAGE_C -D__SIZE_TYPE__=unsigned int -D__PTRDIFF_TYPE__=int -D__EXTENSIONS__ -D_SGI_SOURCE -D_LONGLONG -D_MIPS_FPSET=16 -D_MIPS_ISA=_MIPS_ISA_MIPS1 -D_MIPS_SZINT=32 -D_MIPS_SZLONG=32 u9fs.c /var/tmp/ccDttncm.i
3631 The Business Controls Communicator has been renamed to the GFS Process Assurance Communicator.
3632 We don't write anything in Perl anymore, because [ksh93] has all the functionality built in. - David Korn, quoted on Slashdot
3633 mk: no recipe to make 'rio.data.fsys.menu.scrl.time.util.wctl.wind.xfid.'
3634 Lucent Technologies and strategic partner Fatbrain are pleased to announce ...
3635 artist: unrecognized message 'Elvis Costello'
3636 It's not only stupid it's wrong!
3637 Routers don't need IP addresses. -- Alex Mezhibovsky
3638 syntax error on line 1, teletype / syntax error on line 1, teletype * 0000110 e9 u 8a h ? q m P ` { a7 $ d4 | + ~ = /
3639 So long as system messages are phrased as if a patronising aunt were addressing a retarded 4-year-old, they will continue to love it. - Patrick Ford on Macheads
3640 NT password change form: Password Change Unsuccessful: DS getobject failed for WinNT://AP01/na01\presotto: Error 80005004,.
3641 I hope my TV's software update finishes before Gilligan's Island is on.
3642 rc: Usage: whatis name ...: fd out of range or not open
3643 System time is a count of 100-nanosecond intervals since January 1, 1601. - Windows DDK Docs
3644 There is insufficient memory. Save your document now. - Microsoft Word
3645 0x00FFFFFFUL (ˈɒfəl). Also 4 ofall, 5 offale, -aile, 6 offalle, -awle,
3646 The reasonable man adapts himself to the world; the unreasonable man persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man. -- George Bernard Shaw
3647 A woman is only a woman, but I'm awfully good company. - Bill Gates
3648 It is most enjoyable to talk with you.
3649 Lucky Numbers 12, 14, 19, 24, 36, 43
3650 Lucky Numbers `{seq 100}
3651 junk: 644 mode. Remove ? (yes/no)[no] :
3652 Pharr is about a day and a half.
3653 OBJECTS IN MIRROR ARE CLOSER THAN THEY APPEAR
3654 I found VC++ GUI programming more grief than COBOL using cards! :-)
3655 "If blackouts are going to occur, there's no reason for us to be kept in the dark," Governor Davis said.
3656 --24 May 2001 Trojans are Stealthy, Damaging and Tenacious
3657 (gdb) maintenance demangle __17__class_type_infoPCcPCQ217__class_type_info9base_infoUl
3658 Registering your product will also allow us to contact you in the unlikely event that you need adjustment or modification. - Sony registration card.
3659 Chinese Web Site Replaces CEO.
3660 Today is `pissed off at GNU software' day.
3661 You have less than .027278% chance of getting this fortune. Aren't you lucky?
3662 You can pick your friends, and you can pick your nose, but you can't pick your friend's nose.
3663 The goal of the experimental trials with the artificial heart is to "double the life span of these patients" to 60 days, Lederman said.
3664 I prefer other's wives, but my own toilet. - Japanese proverb
3665 /bin/../lib/gcc-lib/i386-lucent-plan9/3.0/../../../../i386-lucent-plan9/lib/i386-lucent-plan9/3.0/
3666 What Jesus fails to appreciate, is that it's the meek that are the problem.
3667 XML is the Lisp of the 90's.
3668 # DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
3669 Gpklinux uses ld.so 1.9.11 libc6 2.1.3 libc5 5.4.46 binutils 2.9.5.0.37 gcc 2.95.2
3670 The dreck was my idea. - Samuel Z. Arkoff
3671 Please email me off-list if you wish to discuss off-topicness. -Rick Hohensee
3672 I have an x86 assembler in Bash. Would that be helpful for porting Plan 9 libs to unix? -Rick Hohensee
3673 Caches aren't architecture, they're just optimization. - Rob Pike
3674 I will inform you soon later.
3675 Formatting 20,00.77M - Windows 95
3676 Far Knuth!
3677 canlock: corrupted 0xcafebabe
3678 And the fear of you shall be the noise of a broiled fish, and all creeping things that creep upon the earth.
3679 Child process unexpectedly missing: No child processes.
3680 proto.c:435 syntax error, last name: WRONG
3681 The output string must have enough room, or else. - comment in VMware XFree86 driver
3682 gcc -c -O2 -fno-strength-reduce -ansi -pedantic -Wall -Wpointer-arith -I. -Ipublic -Ivmx/public -I../../../../../../programs/Xserver/hw/xfree86/common -I../../../../../../programs/Xserver/hw/xfree86/os-support -I../../../../../../programs/Xserver/mfb -I../../../../../../programs/Xserver/mi -I../../../../../../programs/Xserver/hw/xfree86/int10 -I../../../../../../programs/Xserver/cfb -I../../../../../../programs/Xserver/hw/xfree86/xaa -I../../../../../../programs/Xserver/hw/xfree86/rac -I../../../../../../programs/Xserver/hw/xfree86/vgahw -I../../../../../../programs/Xserver/hw/xfree86/fbdevhw -I../../../../../../programs/Xserver/hw/xfree86/ramdac -I../../../../../../programs/Xserver/hw/xfree86/ddc -I../../../../../../programs/Xserver/hw/xfree86/i2c -I../../../../../../programs/Xserver/Xext -I../../../../../../programs/Xserver/hw/xfree86/xf8_32bpp -I../../../../../../include/fonts -I../../../../../../programs/Xserver/include -I../../../../../../exports/include/X11 -I../../../../../../programs/Xserver/hw/xfree86/xf24_32bpp -I../../../../../../programs/Xserver/hw/xfree86/shadowfb -I../../../../../../include/extensions -I../../../../../../programs/Xserver/hw/xfree86/os-support/vbe -I../../../../../.. -I../../../../../../exports/include -Dlinux -D__i386__ -D_POSIX_C_SOURCE=199309L -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -D__NO_STRING_INLINES -D_GNU_SOURCE -DSHAPE -DXINPUT -DXKB -DLBX -DXAPPGROUP -DXCSECURITY -DTOGCUP -DXF86BIGFONT -DDPMSExtension -DPIXPRIV -DPANORAMIX -DRENDER -DGCCUSESGAS -DAVOID_GLYPHBLT -DPIXPRIV -DSINGLEDEPTH -DXFreeXDGA -DXvExtension -DXFree86LOADER -DXFree86Server -DXF86VIDMODE -DSMART_SCHEDULE -DBUILDDEBUG -DX_BYTE_ORDER=X_LITTLE_ENDIAN -DNDEBUG -DFUNCPROTO=15 -DNARROWPROTO -DIN_MODULE -DXFree86Module -DPSZ=8 -fPIC bits2pixels.c
3683 If your home page is where your heart is, here's where to stay: University Park HOTEL@MIT
3684 A lie of omission is still a lie.
3685 Mountains come out of the sky and they stand there!
3686 The gun law in Queensland is as follows: if you run out of petrol don't run out of bullets.
3687 America? Astounding! All because of a fellow named Columbus and poor navigation!
3688 Warning: MS SQL message: Login failed for user 'webreadonly'. Reason: Not associated with a trusted SQL Server connection. (severity 14) in C:\Inetpub\www.escient.com\buy.php on line 136
3689 uname: not super user
3690 2001.08.30=11:45:58.88-0400 transcript/666/12016387293 nutmeg[667] transcript: Daisy: Please say, Daisy its David or David. Or say, Daisy its me, so I know who you are.
3691 Does anyone have Richard Stallman's phone number? I want to call him and tell him exactly what I think of his software. Criticism wants to be free. -dhog
3692 Devil Duckie, when you float, it's like I'm bathing in a flaming moat!
3693 Djahavagooweegend?
3694 Free Dmitri - with every e-book!
3695 Due to the sophisticated nature of DSL, Verizon Online cannot guarantee uninterrupted or error-free service, or the speed of your service.
3696 %HVHI-W-TOOMUCHQI, Your QI level has exceeded your daily quota. Please log off now!
3697 In the bad old days you'd just write a five line function to [calculate a CRC]. In the good new days, you declare a CRC class with at least three constructors, a destructor, a copy constructor, an assignment operator, a Calculate method, and then you make the calculated value private because God forbid people should be allowed to access it directly and then you need an accessor method, or why not have several such as GetCRCAsFormattedString I think I'll go and lie down now it must be time for my medication. - Andrew Simmons
3698 eThay ummarysay orfay isthay Apanesejay agepay ontainscay aracterschay atthay annotcay ebay orrectlycay isplayedday inway isthay anguagelay/aracterchay etsay.
3699 Subject: MVS Host "ET" Change - Connect:Direct(NDM) & TSO
3700 You can't tell a book if the title is covered.
3701 It's not impossible - just really unfair.
3702 I hate nostalgia. I hated it then and I hate it now.
3703 cvs [checkout aborted]: cannot rename file .new.glwdrawin to glwdrawingareamakecurrent.gl: Invalid argument
3704 Strong vinegar will break its own vessel.
3705 It's impossible to hold two watermelons in one hand.
3706 He lost both Ali-pilaf and Vali-pilaf.
3707 When things don't go right, even halva will break your tooth.
3708 He can't crumble dumplings for himself, yet he cuts noods for others.
3709 He who burns his mouth on milk will blow on yogurt when eating it.
3710 If you don't have honey, have a honey tongue.
3711 My little pilaf and I won't have headache.
3712 To be hungry is better than to be in debt.
3713 Better to eat cheese and bread than pilaf that is given as a favor.
3714 He who pities his lamb can't eat kebab.
3715 The molla saw pilaf and forgot about the Koran
3716 I bought doshab; it turned out to be honey.
3717 Neither cooked at home nor brought from the neighbor's.
3718 Give a gift, never mind if it's a rotten nut.
3719 He is a man who gives bread.
3720 No one calls his ayran sour.
3721 The curd seller will come to our yard, too.
3722 When a tree bears much fruit, it bends low.
3723 You haven't eaten the goose's meat, so you don't know how it tastes.
3724 You don't have a cherry orchard so how do you know what kind of bird a quail is.
3725 Don't offer "bahmaz" to someone who has honey.
3726 How can a donkey know what saffron is?
3727 He has his bread on his knees.
3728 He is one who treads on bread.
3729 You don't give milk to a the child who doesn't cry.
3730 Your mouth won't get sweet just by saying "halva-halva".
3731 Neither meat, nor fish.
3732 We cut salt and bread together.
3733 Say "hello" 40 times to the place where you have tried salt at least once.
3734 Even if your relative eats your meat, he will never discard your bones.
3735 Apricots in the orchard brought so many greetings. When the apricots were gone, so were the greetings.
3736 Be hungry, but don't beg.
3737 Count the chickens in autumn.
3738 Whatever you put on your pilaf will appear on your spoon.
3739 If it works, yogurt; if not, ayran.
3740 Even if the onion is sharp, it has its own place on the table.
3741 Today's egg is better than tomorrow's hen.
3742 My advice to you: grind your own grain.
3743 Don't put garlic on your head if it doesn't hurt.
3744 You can't make stew with cheap meat.
3745 Don't eat "turshu" in front of a sick man.
3746 He gets wool from eggs.
3747 He scoops cream off water.
3748 When you're young, carry stones. When you're old, eat pilaf.
3749 Milk pilov is good one day at our place, the next day at yours.
3750 He doesn't pay for the meat, but grabs the biggest "kuftas".
3751 I neither kneaded nor baked, but I found a ready cake.
3752 WARNING: terminal is not fully functional
3753 - (press RETURN)
3754 Makefile:7: *** missing separator (did you mean TAB instead of 8 spaces?). Stop
3755 Dear Knowledge Management Network,
3756 WAP is crap.
3757 Belvime i no send this mail for make spam!
3758 Absquotilate it in style, you old skunk,..and show the gentlemen what you can do.
3759 Promoting XEmacs from Editors to Red Hat Linux
3760 DO NOT BE SELFISH! SHARE YOUR TIME WITH AN AWESOME SOLE MATE
3761 If emacs buffers were limited to the size of memory, it would not be possible to edit /dev/mem. -tb@becket.net
3762 Linux: written by amateurs for amateurs. - D. Presotto
3763 With free-friends like that who needs free-enemies?
3764 When will they understand the difference between an unmitigated disaster and a total catastrophe?
3765 This is not LINUX! This is Plan 9. There are rules. -boyd/walter
3766 GCC is like a very large city. None of it makes sense, but its citizens cannot escape from it. -Lucio De Re
3767 Subject: Unidentified subject!
3768 Wenn ist das Nunstück git und Slotermeyer? Ja!...Beiherhund das Oder die Flipperwaldt gersput!
3769 A person who knowingly causes a nuclear weapon explosion...is guilty of an offence. - British Prohibitions and Inspections Act 1998 s47(1)(a)
3770 msgPtr->EMM_RSP_OLC_ACK_FWD_H2250LCACKP.bit_mask &= ~EM_H2250LCAP_dynamicRTPPayloadType_present;
3771 Cookie import from '/usr/dhog/lib/cookies' failed: fil
3772 Reality has got to stop! --Mel Lastman, Mayor of Toronto
3773 Do you want to restart now?
3774 Completed updating files, continuing to load Windows...
3775 Enter your network password for Microsoft Networking.
3776 Updating System Settings...
3777 Give me source! Give me challenge! Give me ideas and theory and a fresh way at looking at our life! For people who crave knowledge and really want to understand our world there will always be smart projects like Plan 9. -- northern_snow78@yahoo.com
3778 Alas! The onion you are eating is someone else's water lily.
3779 Friends are better than monkeys.
3780 ODBC API Function SQLGetPrivateProfileString is not currently implemented. Further warnings will be suppressed. hello world
3781 More Not-Yet-Published Bestsellers - category on amazon.com
3782 So, according to Rob Pike, "Window Systems Should Be Transparent", eh? Fortunately, Mac OS X supports *that* feature! - Brendan Connell
3783 cat: read failed: Reached the end of the file.
3784 Windows XP ... is the ``most reliable Windows ever.'' To me, this is like saying that asparagus is ``the most articulate vegetable ever.'' - Dave Barry
3785 Missouri loves company.
3786 Why do you think a country that cannot measure in metric will switch to IPv6?
3787 To me, dynamic libraries are like clowns. In both cases, I was frightened by one at an impressionable age and have loathed them ever since (Bozo tripped on his microphone and fell on me when I was 3, Multics got me at college). - Dave Presotto
3788 The ``Never put snow on a frostbitten part'' virus has been detected within Lucent Technologies. This virus arrives in email with a subject: Why polish the corners off a sphere in a roomful of cubes?
3789 Welcome To Slide Card
3790 I didn't want to be frustrated my whole career, so I moved into computing instead. -Douglas Gwyn
3791 O Factotum, velut luna, statu variabilis!
3792 ls: /n/x/*start*: "/n/x/*start*" "./*start*" "./n/kfs/inferno/*start*" does not exist
3793 Too many color components: 0, max 10
3794 A sheet of sandpaper makes a cheap and effective substitute for costly maps when visiting the Sahara.
3795 A mouse trap placed on top of your alarm clock will prevent you from rolling over and going back to sleep.
3796 rio: can't open display: initdisplay: /dev/draw/new: "/env/tabstop" file does not exist
3797 The full documentation for cat is maintained as a Texinfo manual. If the info and cat programs are properly installed at your site, the command "info cat" should give you access to the complete manual.
3798 Whether the stone hits the pitcher or the pitcher hits the stone, it's going to be bad for the pitcher.
3799 Subject: Convenience Center Equipment Training
3800 So, I'm getting on now, and people ask me, `What's it like to be old?' And I tell them ... I don't feel old, I feel young -- except there's something wrong with me. - Chuck Jones
3801 Thank You for Logging Out!
3802 **THIS IS AN AUTOMATED MESSAGE FROM SOFTSHOE**
3803 Perhaps we could also have a special section for the words of the prophet Bushnell, crying out in the wilderness - "The GNU Public Licence is a jealous Licence, Thou shalt have none other Licence but me" - andrew@mbmnz.co.nz
3804 My belief is Sean's belief is Phil did it all wrong. - Sean Quinlan.
3805 Ten Years Experience. New Needle. - sign on tattoo parlor
3806 Please: Do Not Touch. Do Not Turn Crank. (This is Art: Nothing will happen if you turn the crank except that it might fall off.)
3807 The Journal will accept papers and letters in Microsoft Word only.
3808 That's nothing.. RMS sent me a .doc file the other day...
3809 Belief is the death of intelligence.
3810 ls: /usr/ken/bin: phase error -- cannot happen
3811 To opt out from future mailings CLICK HERE
3812 The X server config file can be found in a range of locations. These are documented fully in the XF86Config(5x) manual page.
3813 Welcome to First Time Wizard.
3814 panic: cannot happen? -rsc
3815 Select 'Yes' if you need a Logo Motion on boot.
3816 The Electric God, the Fire God, all came out to help the Falun in clearing up evil demons with their supernormal capabilities resembling electricity, fire, and tornadoes.
3817 These actions are prohibited by law if you do not accept this License.
3818 gcc.c:610: warning: string length `930' is greater than the length `509' ISO C89 compilers are required to support
3819 One finger can't open up an anus.
3820 The path to enlightenment requires no software.
3821 Notegroups! They kill you!
3822 Question: Did you ever have an important idea that you wanted to jot down, but... your portable, fold-up keyboard is all folded up in your pocket, and there isn't any flat place around to set it up on anyway?
3823 Let's take Stallman's opinions and agree with them, even though we're not sure what he's talking about. -- someone on slashdot
3824 They call themselves flower children but all I see is a lot of weed.
3825 One in three criminals have cats.
3826 "I instructed people on the team to follow the document retention policy, which I knew would result in the destruction of documents." -David B. Duncan
3827 REMINDER! You're About to Get SMART!
3828 Please note, the HomeLink logout button has moved to the upper right hand corner of the screen.
3829 The function will not return until a character is read or the terminal is destroyed.
3830 Expect change, refresh your browser often.
3831 cpp0: Cannot allocate 939136576 bytes after allocating 457620 bytes
3832 I'm Catholic in the same sense that if a cow was born in a tree then it's a bird.
3833 You know, it's interesting, there is a universal God, in my opinion. - George W. Bush
3834 Welcome, rqzgc_mfuv8
3835 String manipulation is more complex than linked list manipulation.
3836 The PSPDN TE sends data to the GPRS TE by use of the GSM PLMN GPRS DNIC.
3837 A non-functioning unit should no longer be used.
3838 Turing's ``imitation game'' eerily presaged today's world of chat rooms, where men pretend to be women, having lesbian cybersex with other women who are, in fact, men. - NYT Magazine, 8/3/2002
3839 Computers are crap, but the Apple store offers a world without toilets. - James Grimmelmann
3840 Please, serious &nbspinquiries only.
3841 He that steals a Bell-weather, shall be discover'd by the Bell.
3842 To avoid undesired effects of optimizing compilers, use the SecureZeroMemory function.
3843 A program that executes more instructions runs slower. - Pike's Law
3844 The identity range managed by replication is full and must be updated by a replication agent. The INSERT conflict occurred in database 'prevacid', table 'PROCESS_CODES', column 'ID'.
3845 Don't go with a spineless ISP. We have more backbone!
3846 *** {02.38.001} Win - Multiple Trillian vulnerabilities
3847 Isn't it funny how people say they'll never grow up to be their parents, then one day they look in the mirror and they're moving aircraft carriers into the Gulf region? - the Onion
3848 If you're like most people, and chances are pretty good that you are, ...
3849 PCMCIA == "People Can't Memorize Computer Industry Acronyms"
3850 Do not be distracted by meaningless messages.
3851 c++ -O2 -fno-exceptions -fno-check-new -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -Wno-long-long -fno-builtin -O -pipe -DBSD -DQT_CLEAN_NAMESPACE -DQT_NO_COMPAT -DQT_NO_ASCII_CAST -o konq main.o mainwindow.o -Wl,-export-dynamic ../kdesrc/kio/http/kcookiejar/.libs/libkcookiejar.a -L/usr/X11R6/lib -ljpeg -L/usr/local/lib -ljpeg -L/usr/lib -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg ../kdesrc/kio/.libs/libkio.a -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg ../kdesrc/kparts/.libs/libkparts.a -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg ../kdesrc/khtml/.libs/libkhtml.a -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg ../kdesrc/kio/http/.libs/libkiohttp.a -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg ../dropin/kparts/.libs/libkpartsdropin.a -ljpeg -ljpeg -ljpeg ../kdesrc/khtml/ecma/.libs/kjs_html.a -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -lssl -lcrypto -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -lqt2 -lpng -lz -ljpeg -lXext -lX11 -lSM -lICE -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -ljpeg -lm -ljpeg -lgcc -lstdc++
3852 Please browse the site to see our full range of services, we can remain customer focused and goal-directed, innovate and be an inside-out organization which facilitates sticky web-readiness transforming turnkey eyeballs to brand 24/365 paradigms with benchmark turnkey channels implementing viral e-services and dot-com action-items while we take that action item off-line and raise a red flag and remember touch base as you think about the red tape outside of the box and seize B2B e-tailers and re-envisioneer innovative partnerships that evolve dot-com initiatives delivering synergistic earballs to incentivize. - www.anadrom.net
3853 If you're calling to report a death, please press or say, "One".
3854 i'm running windows xp under vmware in a vnc on linux being viewed from plan 9. (got that?) - rob
3855 User: support@games.yahoo.com send to you mail with virus. Please check mail in attach !
3856 Subject: I NEED YOUR ASSISTANT
3857 Lucent's motto: Let's make things harder
3858 MOZILLA_FIVE_HOME=/opt/netscape-6.2.3-us
3859 If you haven't heard of XML yet, you must be living under a rock! - Programming in the .NET Environment
3860 The second line computes the sinus of the result. - Programming in the .NET Environment
3861 Where would Christianity be if Jesus got eight to fifteen years, with time off for good behavior? -- New York Senator James H. Donovan on capital punishment.
3862 rsc 5202 0:00 0:00 1710768K Rendez 8.portmapd
3863 http://www.fortunecookieadvertising.com
3864 A short stranger will soon enter your life.
3865 Click Here to GET the penis you want today!!!
3866 The envMaxSize field is the environment file size. It must not exceed envMaxSize.
3867 parser.h:16: ISO C++ forbids declaration of `ConsumeOffendingSymbol'
3868 Click on the following link if you don't want to recieve any more email.
3869 /usr/include/c++/3.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <sstream> instead of the deprecated header <strstream.h>. To disable this warning use -Wno-deprecated.
3870 with venti there's not a simple way to do anything. - rsc
3871 Quidquid latine dictum sit, altum viditur.
3872 static unsigned int minSz = sizeof(uslOBJECT_T);//calculate only the once!
3873 Can be applied directly on top of Tornado AE1.1 Cumulative Patch3, or on top of Tornado AE1.1 Cumulative Patch3 + patch 82607 + patch 83172. Patch 82607 and patch 83172 can not be applied on top of patch 84031.
3874 Existence of this file indicates that the Nautilus configuration druid has been presented. You can manually erase this file to present the druid again.
3875 EXECEPTION TABLE
3876 H e ll o, I a m lo ok in g fo r a ni c e m a n. I f yo u w oul d li k e t o co rre on d wi th m e, pl ea se c li c k t h e li n k be w.
3877 If email advertising won't sell your product than nothing will.
3878 The colorful name kill() harks back to the origin of these interfaces in UNIX BSD.
3879 Earthquakes don't kill people; buildings do. - seismologists' saying
3880 Sorry, There are no Williams-Sonoma stores within 1400 miles of your location.
3881 Few, few the bird make her nest.
3882 Four eyes does see better than two.
3883 So many heads so much opinions.
3884 What come in to me for an ear yet out for another.
3885 The walls have hearsay.
3886 He has a part in the coke.
3887 He has the throat paved.
3888 Its are some blu stories.
3889 He go to four feet.
3890 Nothing some money, nothing of Swiss.
3891 He has discorvered the pot to roses.
3892 Laugh at throat displaied.
3893 That make to come water in the mouth.
3894 To become of bishop miller.
3895 He sleeps as a marmot.
3896 Take the moon with the teeth.
3897 He has a good beak.
3898 He is armed of foot at up.
3899 In the country of blinds, the one eyed men are kings.
3900 To build castles in Espagnish.
3901 Cat scalded fear the cold water.
3902 A take is better that two you shall have.
3903 To eat of the cow mad.
3904 To have a hare memory.
3905 That which feel one's snotly blow blow one's nose.
3906 To be weted even to the bones.
3907 The dress don't make the monk.
3908 The man propose, and God dispose.
3909 To throw the handle afterwards the axe.
3910 Take out the live coals with the hand of the cat.
3911 A horse baared don't look him in the tooth.
3912 Take the occasion for the hairs.
3913 To buy a cat in pocket.
3914 He eat untill to can't more.
3915 He has a good top tongue.
3916 The dog than bark not bite.
3917 It freezes to break the stones.
3918 It want to beat the iron during it is hot.
3919 To the foulish words, no answer.
3920 He is mad to bind.
3921 He has the tongue very free.
3922 He is more in debt but he weigh.
3923 He is a good devil.
3924 He don't know where give with the head.
3925 I upon the night all cats are gray.
3926 The stone as roll not heap up not foam.
3927 Every country has their uses.
3928 They shurt him the doar in face.
3929 With the time come one s to the end of all.
3930 Big head, little sens.
3931 He has fond the knuckle of the business.
3932 Words and feathers the wind carry them.
3933 He turns as a weath turcocl.
3934 A barber shave another.
3935 Belly famished has no ears.
3936 To good appetite it not want any sauce.
3937 There is not better sauce who has the appetite.
3938 The pains come at horse and turn one's self at foot.
3939 It is not for you that the oven is heated.
3940 To force to forge, becomes smith.
3941 Keep the curtains, the farce is played.
3942 Keep the chestnut of the fire with the cat foot.
3943 Friendship of a child is water into a basket.
3944 Burn the politeness.
3945 Tell me whom thou frequent, i will tell you which you are.
3946 After the paunch comes the dance.
3947 Drink as a hole.
3948 Of the hand to mouth, one lose often the soup.
3949 To eat as ogre.
3950 It is a basket bored.
3951 To look for a needle in a hay bundle.
3952 Tu dispute upon the needle top.
3953 To live in a small cleanness point.
3954 It must to break the stone for to have almond.
3955 To make paps for the cats.
3956 To fatten the foot.
3957 To craunch the marmoset.
3958 IF YOU THINK THIS IS SPAM PLEASE REMOVE YOUR EMAIL OUR LIST
3959 Linux programmer's mind: don't invalidate the D-cache unless it wasn't enabled
3960 You should be automatically redirected to the new page in 0 seconds.
3961 `An improvement is something your program will not work with and a bug fix is something it will not work without' -- Roger Needham
3962 PLEASE! Don't urinate on the specimen.
3963 For those who only have time to read Slashdot, may God protect you on your journey towards technical obsolescence. - David Patterson, on Slashdot
3964 Homeland security begins at home. - Seattle mayor Greg Nickels
3965 1 Dir(s) 70,368,744,161,280 bytes free
3966 Has Your Life Been Ruined by Evil?
3967 smtpdaemon is needed by diskcheck-1.4.2 - Red Hat Linux
3968 You want to make your way in the CS field? Simple. Calculate rough time of amnesia (hell, 10 years is plenty, probably 10 months is plenty), go to the dusty archives, dig out something fun, and go for it. It's worked for many people, and it can work for you. - Ron Minnich
3969 Recent studies have proven what most people already know: That most Penis Enlargement Pills are completely useless. We set out to design a program that really works.
3970 From a Walgreen's receipt: I'm JESUS. I'm here to serve you with our "7 Service Basics"
3971 I just realised something... I am NOT a nerd, and none of this stuff matters. I'm Outta Here! - some guy on Slashdot
3972 Everything in UNIX is modelled as a "file", whereas in Plan9 everything is modelled after a "burrito" - some guy on Slashdot
3973 Sense of terminal's easiness and functional file server!
3974 Practically noiseless and impossible to explode. - ad for the 1897 Oldsmobile
3975 info: Terminal type `dumb' is not smart enough to run Info.
3976 k=k; /* To suppress warning */
3977 debug1: Miscellaneous failure
3978 That doesn't make sense to me. But then, you are very small. Perhaps you're right.
3979 A company is only as good as its least imaginative manager.
3980 Thank you for ordering from MEDCO SUPPLY COMPANY, INC., where 100% satisfaction is gu
3981 (mozilla-bin:3115): Gtk-WARNING **: A floating object was finalized. This means that someone called g_object_unref() on an object that had only a floating reference; the initial floating reference is not owned by anyone and must be removed with gtk_object_sink() after a normal reference is obtained with g_object_ref(). - exit message from Mozilla
3982 Hurray! We have successfully exploited a buffer overflow on the plan9 operating system! And most importantly, we did the most useful thing possible: we exited the shell. If you ever gain access to a plan9 box, remember that the smartest thing you can do is logout. - phrack article
3983 You have synapses? I wish I did. My neurons communicate by shouting. It gets pretty noisy in my head. Some times all six of them are shouting at the same time. - presotto
3984 Failed silent installation. May be failed to allocate Memory.!
3985 An extended error was returned from the server. This is typically a string or buffer containing a verbose error message. Call InternetGetLastResponseInfo to retrieve the error text.
3986 If you're not living on the edge, you're taking up too much space.
3987 if_de.c:2401: sc->tulip_mediums[media] = mi;
3988 Please let us know if there is anything we can do to make your stay more magical. Please note the field below is limited to 29 characters. - Disney World hotel reservation web page
3989 Telegraph is a kind of a very, very long cat. You pull his tail in New York and his head meows in Los Angeles. And radio operates exactly the same way — you send signals here, they receive them there. The only difference is that there is no cat. -Albert Einstein
3990 Hi. My name is %{NAME%}%, I am 25 years of age. I happen to see your profile on the internet. Come visit me some more by viewing my site. Ethel
3991 As complicated as the semantics of virtual inheritance may seem, its support within the compiler has proven even more complicated. - Stanley Lippman, Inside the C++ Object Model
3992 Who needs hallucinatory drugs when we've got quantum physics?
3993 The essence of XML is this: the problem it solves is not hard, and it does not solve the problem well. - Phil Wadler, POPL 2003
3994 tcp_extensions="YES". really i wanted "MAYBE" or "GOODQUESTION" or "YOUTELLME" or "YOU'RETHECOMPUTER!" - forsyth
3995 int parse_url(unsigned char *url, int *prlen, unsigned char **user, int *uslen, unsigned char **pass, int *palen, unsigned char **host, int *holen, unsigned char **port, int *polen, unsigned char **data, int *dalen, unsigned char **post)
3996 Please select an Aardvark
3997 This thing is like a quarry where every pebble has something bad hidden underneath - Presotto about the Links source.
3998 fortune 1907: suicide: sys: trap: divide error pc=0x00001b33
3999 i'm not real convinced about this but I could be interesting. - boyd
4000 If you are what you eat, then I'm cheap, fast, and easy.
4001 /@burro.ws: Permission denied
4002 return ({goto L; p;}) && ({L: 5;});
4003 object-oriented design is the roman numerals of computing. - rob
4004 Java is the f*cking COBOL of the 90s, and future generations of geeks are going to fly back from Mars to piss on our graves for inflicting it on them. - rasputnik@hellooperator.net
4005 httpd_server* httpd_initialize(char* hostname, httpd_sockaddr* sa4P, httpd_sockaddr* sa6P, unsigned short port, char* cgi_pattern, int cgi_limit, char* charset, char* p3p, int max_age, char* cwd, int no_log, FILE* logfp, int no_symlink_check, int vhost, int global_passwd, char* url_pattern, char* local_pattern, int no_empty_referers )
4006 it's easier to post to 9fans than to think. - boyd
4007 We assume familiarity with Rubik's Cube, the delights of which cannot be presented adequately in a textual description! - an algorithms textbook
4008 If you are idle for more than 1000 hours, the system will log you out. Please save reviews frequently.
4009 We lead by following standards. - sape
4010 -bash: /home/r/.bash_logout: Permission denied
4011 I am he as you are he as you are me and we are all together. - forsyth after Lennon on authentication
4012 Network services at the Murray Hill, NJ, location (100001) will be unavailable due to UPS (Uninterrupted Power Supply) maintenance from 8:00 p.m. EDT on Saturday, June 26, to 4:00 a.m. EDT on Sunday, June 27.
4013 Don't show this message again.
4014 Service error -27.
4015 Beauty is more important in computing than anywhere else in technology because software is so complicated. Beauty is the ultimate defence against complexity. - David Gelernter
4016 Zatoichi: in theaters December 31, 1969.
4017 recordio.h:992: type `__true_type' is not a base type for type `__false_type'
4018 Telephone number has to be 10 numbers. For example, enter '8002158482'. Please contact us at 1-800-215-8482 for any assitance.
4019 No one but a theorist believes his theory; everyone puts faith in a laboratory result but the experimenter himself. - Einstein
4020 (Okay, Plan 9 isn't Linux, but it's a close relative).
4021 Tux is not cute. Tux has the expression of someone right after knitting needles have been used to scramble the front side of their cerebral cortex. Tux scares me. - Ron Minnich
4022 Setting up your SIP account will allow you to call both other SIP users as well as pstn phones. - Wim Sweldens
4023 ntifs.c(202) : error C2064: term does not evaluate to a function taking 25732904 arguments
4024 There's no "I" in team, but there's both a "me" and an "I" in media.
4025 Oh, I'm sorry, sir, go ahead. I didn't realize you were root.
4026 C++ is to C as lung cancer is to lung.
4027 Warning: bad syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html
4028 Those days [of "one tool doing one job well"] are dead and gone and the eulogy was delivered by Perl. - rob
4029 We have found that the Real Player plugin, which is used by the BBC Radio Player, may or may not function fully depending on a combination of what flavour of unix/linux you are using, which browser you are using, which version of browser you are using, and which version of GCC built the plugin during installation.
4030 Sheer [program] size is often an illusion, reflecting only a need for improvement. - Kernighan and Plauger
4031 bootsplash: silent mode.
4032 Trusting every aspect of our lives to a giant computer was the smartest thing we ever did! - Homer
4033 Courts are not equipped to execute the law. - John Ashcroft
4034 The Ken Thompson school of thought on expert systems: there's table lookup, fraud, and grand fraud. - Andrew Hume, quoted in ;login:
4035 I am Davros, my Daleks are my servers and plan9 is my control board mwahahaha - Matt
4036 What's grey? A melted penguin.
4037 Why don't cannibals eat clowns? Because they taste funny.
4038 Two goldfish are in a tank. One turns to the other and says, "Do you know how to drive one of these things?"
4039 What do software pirates say? CD-Arrrrrrr!
4040 Select only drivers expected to compile cleanly. - Linux kernel configuration option
4041 usage: tar [-][{ruxXtcC}acdefhlm{o|S}pqvwLUBDRV{O|K}fb] [dir] [tapefile] [blocksize] file ...
4042 /opt/exp/lib/firefox/bin/run-mozilla.sh: line 451: 16207 Segmentation fault "$prog" ${1+"$@"}
4043 LoadPlugin: failed to initialize shared library /opt/net/exp/lib/mozilla/bin/plugins/j2re1.4.2/plugin/i386/ns610-gcc32/libjavaplugin_oji.so [/opt/net/exp/lib/mozilla/bin/plugins/j2re1.4.2/plugin/i386/ns610-gcc32/libjavaplugin_oji.so: undefined symbol: _ZdlPv]
4044 This 43 minute video FEATURES the 22 year-old, 6'6" (6'11" in heels) 300+ pound, size 14 shoe size Blythe
4045 Linux is good if you want to run Apache or compile the kernel. Every other application is suspect. - Andrew Hume
4046 /etc/bash.bashrc: alias unmount='echo "Error: Try the command: umount" 1>&2; false'
4047 Book-burning is such an ugly phrase. I prefer to think of it as "English lit". - Larry Hollister
4048 panic: bad rob
4049 ulong when; /* may underflow in clock(); must be signed */
4050 There is no interest in a WWW browser. This fad is clearly not going to have any staying power. - plan.9@research.att.com, Oct 22 1994
4051 the representation of characters, but not the character set itself, was changed this weekend. we believe that the representation we are using now will become the one used by unix-like systems everywhere. - rob's news about utf-8, sep 6 1992
4052 Linux: the world's best text adventure game.
4053 MessageSocket::setHostname(): gethostbyname() failed: Success
4054 /* This variable is here only because of a historical reason. */
4055 It's almost as though someone is creating billboards that read, ``If you can#t splel VaigrA, you cn mkae big $M$O$N$E$Y$ wtih b.ul.k adtervising on teh I*N*T*R*E*N*E*T.'' - Rob Kolstad
4056 And, as you read, please forgive the necessary typos - I'm going for rock-solid facts, rather than spelling.
4057 mp3riot - Directory search utility
4058 val.h:152: class `FloatVal' is implicitly friends with itself
4059 The MOV mnemonic, which stands for `move', is a misnomer. A copy function is actually performed instead of a move. - AMD64 Architecture Programmer's Manual Volume 1
4060 It's not foolproof, but maybe if we don't act like fools, it will work. - Sara O'Brien
4061 May God forgive you for what you have done! - Pope John Paul I, to the Cardinals who elected him
4062 hb = 0x80; hb = hb << 24; /* hb = 0x80000000UL */
4063 setenv I_WANT_A_BROKEN_PS
4064 It's the ship that made the Kessel run in less than twelve parsecs.
4065 CPU0 states: 0.0% user, 150.0% system, 0.0%nice, 0.0% idle
4066 i know what jmk did. he added reentrancy for threads. - boyd, about uintptr
4067 i hate all sorts of zealots - boyd
4068 /* Watch the brackets - even Ken and Dennis get some language design wrong */
4069 Not related to the portable reciprocating power saw trademark of the Milwaukee Electric Tool Corporation.
4070 GNU C++ does not support old-style function definitions, so this extension is irrelevant.
4071 Here we have twenty-eight letters.
4072 Here we have twenty-six letters.
4073 Even if you could revive someone who has died, you haven't really done anything that deals with that person's central problem, which is sin.
4074 Being really good at C++ is like being really good at using rocks to sharpen sticks. - Thant Tessman
4075 A computer is like an Old Testament god, with a lot of rules and no mercy. - Joseph Campbell
4076 Arguing that Java is better than C++ is like arguing that grasshoppers taste better than tree bark. - Thant Tessman
4077 (Of course SML does have its weaknesses, but by comparison, a discussion of C++'s strengths and flaws always sounds like an argument about whether one should face north or east when one is sacrificing one's goat to the rain god.) - Thant Tessman
4078 C++ is history repeated as tragedy. Java is history repeated as farce. - Scott McKay
4079 Applicants must also have extensive knowledge of UNIX, although they should have sufficiently good programming taste to not consider this an achievement. - Hal Abelson, MIT AI Lab job ad
4080 I recently visited plan9.bell-labs.com/wiki/plan9 and I would like to offer my web design services. I can help you with your Plan 9 website. - spam
4081 There are no network problems with scone, hale and poptart. IT support is working these issues and we will notify you when the problem is resolved.
4082 A C, an E-flat, and a G walk into a bar. The bartender says, "Sorry, but we don't serve minors."
4083 exhausted("sleep");
4084 /// The ForTo class avoids confusing syntax of "for (int i=1;i<=4;i++) {...}". This can be replaced with "foreach (int i in new ForTo(1,4)) {...}".
4085 Linux is for people who hate Windows. BSD is for people who love UNIX.
4086 If plan9 was a village then I'd probably be the village idiot, but it would still be better than living in the city. - Dave Lukes
4087 Software has gotten too fat and unreliable, so we started with Linux. - Nicholas Negroponte
4088 Forgive my ignorance, I am a layman and nowadays get my schooling through search engine results. - Vester Thacker
4089 By tradition, the return value of functions report what they did, not what they considered doing. - rob
4090 If the restaurant serves poor beer, don't switch to wine. - sape
4091 There is nothing quite like looking up and seeing YOUR star. Order now for FREE SHIPPING.
4092 gcc is the holy cow of compilers, not the holy grail. - forsyth
4093 NOTE 3: Each bit has the value either ZERO or ONE. - ECMA-035 spec
4094 cpu90112: exiting
4095 cpu0: existing
4096 The operation timed out while trying to contact void.
4097 On the Internet nobody knows you're running Plan 9. - Jim McKie
4098 Deleted code is debugged code. - Jeff Sickel
4099 DEAR ALL, I am newbie! pls guide me,
4100 Google does not appear to be in the kludge-making business ... - Ashlee Vance, The Register
4101 ** the "time" argument is mandatory! (try "now") **
4102 Revision control is like any other form of accountancy -- worthy but dull. -forsyth
4103 There are but 10 types of people in the world. Those who understand the binary numbering system and those who don't.
4104 we live in a world of dogmas, probably trying to fight it with a stronger dogma is a bad idea, but trying to fight it with preumpted objectivism clearly doesn't work. - uriel
4105 Equations are the devil's sentences. - Stephen Colbert
4106 cpu: can't dial: plan9.lanl.gov: The operation completed successfully.
4107 A kiss without a beard is like an egg without salt. - Dutch proverb
4108 Nothing is good enough for the fortune file! - Dan Cross
4109 Tried to read 71776119061217303 bytes. Read only 23
4110 /dev/shm/root has gone 49710 days without being checked, check forced.
4111 x11 code is just so bad. by which i mean bad of course, and not good. - forsyth
4112 Peter Seebach is not POSIX compliant but runs most UNIX applications.
4113 Glyph 390 is called ".notdef", a singularly inept choice of name.
4114 Well, I have tried to learn as much as possible from prior attempts. If nothing else, we are committed to failing in a new way :) - Elon Musk, SpaceX founder
4115 You've got a syntax error somewhere in your code. It could be around line 15. Good luck finding it. - the Mini-C compiler
4116 Lucent is the best place 4 me to work. (Please keep confidential)
4117 It might be comfortable, but so is lounging in a big enough pile of shite. - jmk, about ioctl
4118 i'm sure ken said we had persistant objects: ''they're called files'' - boyd
4119 But macros are like having these high-powered band-aids, when what you want is not to be wounded in the first place. - Steve Yegge
4120 You’ve followed a link to a topic that doesn’t exist yet.
4121 Metaphors about deck chairs abound.
4122 After you have rotated your monitor, you need to complete the procedure below to rotate your operating system.
4123 The human genome is about 3 gigabases long, which boils down to 750 megabytes. Depressingly enough, this is only 2.8 Mozilla browsers. - Bert Hubert
4124 cc: The parameter is incorrect. - cygwin cc
4125 Some people are like slinkies. They don't really have a purpose, but they still bring a smile to your face when you push them down the stairs.
4126 /* Not static, because we don't want the compiler removing it */
4127 It appears that you are accessing Myspace.com from a location that is not authorized to view our licensed videos. Please go to the United States or its territories and try again.
4128 Subject: There's More to Nevada Than You Think
4129 The user of distributed operating systems will know a new kind of reliability. - MIT video about computer networks, 1972
4130 I don't think there's a support group for people who don't have cancer - Fiona McKie
4131 vi vi vi - the roman number of the beast
4132 VFS: Busy inodes after unmount. Self-destruct in 5 seconds. Have a nice day... - Linux
4133 One of the silliest things you can do with a modern Unix machine is run the Eliza mode of Emacs against random quotes from Zippy the Pinhead. - Eric Raymond
4134 * Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE DESCRIBE IT HERE!
4135 Never smack a Bulgarian. - Ron Minnich
4136 The Adobe Updater must update itself before it can check for updates. Would you like to update the Adobe Updater now?
4137 I'm not sure if that's true or not, I got that from an Internet web page:... - Lluís Batlle
4138 We're sorry, the page you're looking for is no longer here.
4139 We've recently reorganized our site and streamlined some of our content. You can look for content using the search box at the top of each page.
4140 /* keep the code below somewhat more readonable; not used elsewhere */
4141 When we order T-Shirts to give away at conferences (like OSCON), we always order "Medium", "Large", "Extra-Large", and "Programmer" sizes. _ Randal Schwartz
4142 THANK YOU FOR AN INTERESTING GAME.
4143 main: 7,913,578,496 used + 35,178,551,926,784 free = 2,093,416,448 (378% used)
4144 Bitfield endianness not defined! Check your byteorder.h
4145 All I know about print is that you can do it too soon. - Ron Minnich
4146 acid: <stdin>:82: (error) 82: <eof> eating symbols
4147 1 2034 9/01 17:54 god@bell-labs.com bye
4148 Girija pointed out a couple of bugs (I think of them as typos myself :-) -Sape
4149 Plan 9 makes BeOS look like a market leader.
4150 I'm doing it very slowly, so results will be as soon as possible...
4151 GTK+ is written in high quality object-orientated C. - Programming with gtkmm
4152 swapon: /dev/disk/by-uuid/928aaabd-5744-4f0a-b9ef-aa101f286514: Invalid argument - Linux
4153 We apologize for any inconvenience this causes - Lucent Convenience Centers
4154 Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems. - Jamie Zawinski
4155 [Perl] combines the power of C with the readability of PostScript. - Jamie Zawinski
4156 Subclass code (assigned by the USB-IF). Indicates which industry standard command block definition to use.
4157 Globus is an unstoppable monster - rminnich; No, Globus is an unstartable monster - ericvh.
4158 Multithreading is just one damn thing after, before, or simultaneous with another. - Andrei Alexandrescu
4159 ArrayList of int / my list of int, equals new / ArrayList of int - Steve Yegge
4160 In the land of the clueless, the man with half an idea is king. - Todd Robbins
4161 Chebyshev said it, and I say it again / There is always a prime between n and 2n. - Paul Erdös
4162 Using Linux is like rediscovering your childhood and realising it really was pretty miserable. - jmk
4163 remove is identical to install except that packages are removed instead of installed. If a plus sign is appended to the package name (with no intervening space), the identified package will be installed instead of removed. - apt-get(8)
4164 I guess the idea is that ... even though the structures are all different. Everythings fine, dont worry, lie back and think of England. ... I think we can call it Pollyanna-morphism. -- Ron Minnich on Python libraries.
4165 Can't get device information: Success -- Linux Bluetooth discovery.
4166 Linux is neither Unix nor Windows — it's the worst of both worlds -- jmk
4167 Did you ever try to write poetry in a committee meeting? It's like a bunch of fat construction guys trying to write an opera while sitting on the couch watching Baywatch. The more fat construction guys you add to the couch, the less likely you are to get opera out of it. - Joel Spolsky
4168 Don't interrupt! Let me finish! - Rae McLellan
4169 bool x = "false"; // valid C++ [sets x to true]
4170 # The below line not be changed otherwise we refuse to work
4171 having read AF_UNIX(7) i'm still don't see the point. portable programs should not do this. portable programs should not do that. the details of this varies from implementation to implementation. none of the following socket things ... are implemented. the name is limited to 107 bytes. - forsyth
4172 Please wait. This can take some time.
4173 I love troff. It reminds me of runoff, which reminds me of my youth, when VMS was in flower and knowledge of EDT and runoff was all a lad needed to make a good living as a tech writer. - Frank Willison
4174 General Internet error has occurred. - [OpenOffice.org 2.0]
4175 Remember to drink responsibly during this St. Patrick's Day season.
4176 File under POPULAR: Male Vocal - Syd Barrett LP sleeve
4177 N = C + {fb (cm) . fb (tc)} + fb (Ts) + fc . ta, where N=force in Newtons required to break the cooked bacon, fb=function of the bacon type, fc=function of the condiment/filling effect, Ts=serving temperature, tc=cooking time, ta=time or duration of application of condiment/filling, cm=cooking method, C=Newtons required to break uncooked bacon
4178 #define v6addrcurr(lifc) (( (lifc)->origint + (lifc)->preflt >= (NOW/10^3) ) || ( (lifc)->preflt == 0xffffffff ))
4179 It seems that subjective C is more popular than objective C - brucee
4180 Eta aquarid meeteeor shouwer - astro -k
4181 The program 'apt-get' is currently not installed. You can install it by typing: apt-get install apt - ubuntu linux
4182 Subject: Re: [9fans] speaking of kenc... can you imagine a c compiler that does not translate to asm first? or can you imagine porting a c compiler when you dont have an assembler? -- Rogelio Serrano
4183 I expect to be quite wealthy once the dust from the Linux IPOs has settled. - Eric Raymond, "Doing It For the Cause", December 1999
4184 A handful of characteristics of Unix are responsible for its resilience. First, Unix is simple: whereas some operating systems implement thousands of system calls and have unclear design goals, Unix systems typically implement only hundreds of system calls and have a very clear design. -- Linux Kernel Development, 2nd Ed. by Robert Love
4185 IF YOU CAN HEAR THUNDER...YOU ARE CLOSE ENOUGH TO BE STRUCK BY LIGHTNING.
4186 If you go and talk to our people and ask why they are doing something, they will give you a good reason why they are doing it. - Ravi Sethi, President, Avaya Labs Research
4187 hi uriel!
4188 Gianfranco Luigi per tutti bezahlen.
4189 Science is what we understand well enough to explain to a computer. Art is everything else we do. - Donald Knuth
4190 process `sysctl' is using deprecated sysctl (syscall) net.ipv6.neigh.eth1.base_reachable_time; Use net.ipv6.neigh.eth1.base_reachable_time_ms instead.
4191 There is absolutely no warranty for GDB. Type "show warranty" for details.
4192 Th' canny man keeps his money in sheep - or he keeps it in th' First Presbyterian Bank o' Scotland
4193 ttcp-r: 3689238521928343900000000000000 bytes in 41.02 real seconds = 87829643931512629000000000.00 KB/sec +++
4194 By the time you finish reading this article, you will be able to take advantage of the coolest file system feature to be implemented since the symbolic link. - CLI Magic: Use Extended Attributes for better file management By Ryan Paul
4195 Intel Pentium 4 2.0Hz processor - TigerDirect catalogue
4196 You are roughly 2^90 times more likely to win a U.S. state lottery *and* be struck by lightning simultaneously than you are to encounter [an accidental SHA1 collision] in your file system. - J. Black
4197 prelink - prelink ELF shared libraries and binaries to speed up startup time
4198 schedule(); // XXX poll? waitqueues?
4199 gsoc | doc archive | uriel | harmful | 9P | cat-v.org
4200 /*FIXME: what about parameter checking: context, etc? have a macro too? */
4201 Results 1 - 10 of about 34,900,000 for all else is the work of God.
4202 This is Radio Clash on pirate satellite.
4203 We already agreed on a solution. Nobody is interested in implementing it. - Lucho
4204 This resource fork intentionally left blank
4205 checking size of char... 1 - gnu configure
4206 Nobody wants to argue with Knuth – it is the equivalent of arguing against the second law of thermodynamics. - Mick West
4207 Customer stickiness reduces churn making it a valuable benefit.
4208 SIP is the Linux of telephony. - Sape
4209 There was an error during the CUPS operation: 'client-error-not-possible'.
4210 The following recipient(s) could not be reached: OpenView Service Desk on 11/7/2007 4:24 PM The message could not be delivered because the recipient's mailbox is full. - automated response to mail complaining that limits on mailbox size are too low
4211 Dear Valued Customer #88143191!
4212 rusty: kernel pseudo files are not the place for chit-chat
4213 I define UNIX as ``30 definitions of regular expressions living under one roof.'' - Don Knuth
4214 ADDITIONAL METAPHOR SPOILER ALERT: ``The Old Man and the Sea'' is not just about an old man and the sea.
4215 2008-06-18 00:00:37: [650] DEBUG: msg 5 not interesting
4216 Your IP address is: <? echo getenv('REMOTE_ADDR'); ?>. By continuing to browse this website, you agree to the following terms.
4217 /* dummy = malloc(0); *//* prepare for garbage-collection */
4218 You chose to apply Shadow Ram extend feature, while you knew it was risky. If the system hangs during boot, please restart the system and come here to change the setting.
4219 An amateur thinks it's really funny if you dress a man up as an old lady, put him in a wheelchair, and give the wheelchair a push that sends it spinning down a slope towards a stone wall. For a pro, it's got to be a real old lady. - Groucho Marx.
4220 Error Code: -2147483648
4221 Pardon the abruptness of this letter; it is due to its exigency.
4222 The source of the money is legal and authoritative.
4223 Please note that I do not intend to waste my time and yours.
4224 The Internet is still a fascination to me.
4225 Sometimes one needs to take chances.
4226 #define MIG_ARRAY_TOO_LARGE -307 /* array not large enough */
4227 If you cannot read this, reply. Otherwise, disregard. - Pietro Gagliardi
4228 "Come _on_. I'm not that subtle a 'baiter,' or... am I?" - Eris Discordia: "You're a master baiter." - Skip Tavakkolian
4229 Your Real Estate Building Service request has been completed. Your service request number 110738516 - DEAD MOUSE IN GLUE TRAP - 2C501 was completed on 10/07/2008.
4230 Your Real Estate Building Service request has been completed. Your service request number 110740079 - Remove Squirrel - 2C-516 was completed on 10/21/2008.
4231 Sorry but there is no description for this item ... (less)
4232 Sorry but there is no description for this item ... (more)
4233 NOTHING FOLLOWS
4234 The problem is there's no data to fake yet. - Noah Evans
4235 `You could pound nails with [the Motorola StarTAC] and it still worked. This phone is like that: you could set it on fire, and you'd still get your e-mail.'
4236 Cookies! Thanks NFS Anonymous Access User!
4237 Closing this window will terminate the running processes: login, bash, acme, acme, devdraw, 9pserve, win, win, win, win, win, win, win, win, win, win, win, win, win, win, win, win.
4238 "Transitive trust is metastable." - Brucee on the banking crisis in 2008
4239 Your Real Estate Building Service request has been completed. Your service request number 110746368 - 2C523, BIRD FLYING AROUND IN CORRIDOR,MH was completed on 12/22/2008.
4240 There is no organization (dept/cost center) in Lucent Technologies whose name matches "convenience"!
4241 buf[0] = '\0'; /* make sure it's empty (silly 3b2) */
4242 #ifndef bool /* Linux 2.6.19 C++ nightmare */
4243 slashdot: the consensus of the ill-informed - brucee
4244 "People aren't wearing enough hats" - Truism from brucee
4245 to kill the postman that delivered this email to you press here
4246 A Man is rich in proportion to the number of things he can afford to let alone. -Thoreau
4247 Just getting something to happen might be training, but it sure isn't education. -Brian L Stuart
4248 This page has an unspecified potential security flaw. Would you like to continue?
4249 Comeau C/C++ 4.3.10.1 beta: Now in our 22nd year!
4250 size: q.out not an a.out
4251 Sharing your DNA hasn't been this exciting since the good old days. - Genealogy.com
4252 *WASH_Eyes_outWith_soap*
4253 -rwxr-xr-x 1 rae rae 141307906 Nov 10 16:55 arm-2009q3-67-arm-none-linux-gnueabi.bin # shell script
4254 Beam to 1.04TeV... Lost due to tune drifting [sh*t!]... Tunes for beam 1 were different when we returned to injection energy (no precycle)... Trimmed and incorporated... Ramped 2 beams, all the way to 1.18TeV !!
4255 anguish up -1 days, 00:00:01
4256 People admire complexity. - Rob Pike
4257 Due to a technical error with the distribution of Ottawa Newsbreak, you may have received the newsletter this morning. Please accept our apologies.
4258 DON'T throw lefts of coffee, tea or chocolate milk into this recipient! Thank you.
4259 You tried to access the address opera:crossdomainerror, which is currently unavailable. Please make sure that the Web address (URL) is correctly spelled and punctuated, then try reloading the page.
4260 Mandatory options: - xen-create-image(8)
4261 We are unable to complete the check-in process at this time. Please proceed to the airport for assistance.
4262 As low as possible isn't a number yet - Ron Minnich
4263 Tip: Save time by hitting the return key instead of clicking on "search".
4264 ./home/gri/go1/doc/test.go:3:1: expected declaration, found 'IDENT' notwithstanding
4265 rm: remove write-protected regular empty file `some_random_file'?
4266 !factotum protocol botch 0 ok bad authentication failed
4267 exception: <type 'exceptions.AttributeError'>: 'NoneType' object has no attribute 'exception'
4268 what bug does this fix that you think you've fixed that addresses this particular bug? - erik quanstrom
4269 With functional programming languages, you can never make small mistakes, only very large ones. - Kedar Namjoshi
4270 Subject: Departs: 7:00 PM Thu Dec 02 2010 Washington, DC - Union Station (WAS) Station News Arrives: 9:16 PM Thu Dec 02 2010 Metropark- Iselin, NJ (MET) Metropark-Iselin, NJ Metropark-Iselin (MET) Station News PT2H16M Duration: 2 hr, 16 min (Internal Document ITD-10-49997V)
4271 complete SoC on a chip - Tilera
4272 There is no application installed for executable files. Do you want to search for an application to open this file?
4273 There's no 'I' in team, but there's a 'u' in suck.
4274 Mandatory post fields are username,password,backto
4275 Spa Rood, met toegevoegd koolzuur -> Shovel red, with added cabbage heartburn. - Yahoo! Babel Fish
4276 Everything happens automatically and there is nothing new to learn. - Steve Jobs
4277 wrong malign list
4278 Sorry you try to use the function during a critical time. Out of technical reasons between 3:30 and 5:00 WET and 15:30 and 17:00 WET activations may be lost.
4279 Major funding for The Fabric of the Cosmos is provided by the National Science Foundation and the Alfred P. Sloan Foundation.
4280 i dont understand the physical processes that will produce a 40 year fifo. -ken, after receiving the Japan Prize in 2011
4281 Polydactyly mutations relax control of sonic hedgehog. - Armand Marie Leroi
4282 Your 20333x1 screen size is bogus. Expect trouble. - Linux ps
4283 Bonjour &FIRSTNAME;
4284 We are experiencing some technical difficulty. Please contact our support team and provide them the reference number below. Error Reference: $referenceNumber
4285 User Modification Interface: UIM is currently down for maintenance.
4286 people who program actually have a lot to learn from the fashion industry. -someone on hacker news
4287 runtime: out of memory: cannot allocate 70367670501376-byte block (1048576 in use)
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 // Structural transactions.
5
6 package lldb
7
8 //DONE+ TransactionalMemoryFiler
9 // ----
10 // Use NewRollbackFiler(myMemFiler, ...)
11
12 /*
13
14 bfBits: 3
15 BenchmarkRollbackFiler 20000000 102 ns/op 9.73 MB/s
16
17 bfBits: 4
18 BenchmarkRollbackFiler 50000000 55.7 ns/op 17.95 MB/s
19
20 bfBits: 5
21 BenchmarkRollbackFiler 100000000 32.2 ns/op 31.06 MB/s
22
23 bfBits: 6
24 BenchmarkRollbackFiler 100000000 20.6 ns/op 48.46 MB/s
25
26 bfBits: 7
27 BenchmarkRollbackFiler 100000000 15.1 ns/op 66.12 MB/s
28
29 bfBits: 8
30 BenchmarkRollbackFiler 100000000 10.5 ns/op 95.66 MB/s
31
32 bfBits: 9
33 BenchmarkRollbackFiler 200000000 8.02 ns/op 124.74 MB/s
34
35 bfBits: 10
36 BenchmarkRollbackFiler 200000000 9.25 ns/op 108.09 MB/s
37
38 bfBits: 11
39 BenchmarkRollbackFiler 100000000 11.7 ns/op 85.47 MB/s
40
41 bfBits: 12
42 BenchmarkRollbackFiler 100000000 17.2 ns/op 57.99 MB/s
43
44 bfBits: 13
45 BenchmarkRollbackFiler 100000000 32.7 ns/op 30.58 MB/s
46
47 bfBits: 14
48 BenchmarkRollbackFiler 50000000 39.6 ns/op 25.27 MB/s
49
50 */
51
52 import (
53 "fmt"
54 "io"
55 "sync"
56
57 "github.com/cznic/fileutil"
58 "github.com/cznic/mathutil"
59 )
60
61 var (
62 _ Filer = &bitFiler{} // Ensure bitFiler is a Filer.
63 _ Filer = &RollbackFiler{} // ditto
64 )
65
66 const (
67 bfBits = 9
68 bfSize = 1 << bfBits
69 bfMask = bfSize - 1
70 )
71
72 var (
73 bitmask = [8]byte{1, 2, 4, 8, 16, 32, 64, 128}
74 bitZeroPage bitPage
75 allDirtyFlags [bfSize >> 3]byte
76 )
77
78 func init() {
79 for i := range allDirtyFlags {
80 allDirtyFlags[i] = 0xff
81 }
82 }
83
84 type (
85 bitPage struct {
86 prev, next *bitPage
87 data [bfSize]byte
88 flags [bfSize >> 3]byte
89 dirty bool
90 }
91
92 bitFilerMap map[int64]*bitPage
93
94 bitFiler struct {
95 parent Filer
96 m bitFilerMap
97 size int64
98 sync.Mutex
99 }
100 )
101
102 func newBitFiler(parent Filer) (f *bitFiler, err error) {
103 sz, err := parent.Size()
104 if err != nil {
105 return
106 }
107
108 return &bitFiler{parent: parent, m: bitFilerMap{}, size: sz}, nil
109 }
110
111 func (f *bitFiler) BeginUpdate() error { panic("internal error") }
112 func (f *bitFiler) EndUpdate() error { panic("internal error") }
113 func (f *bitFiler) Rollback() error { panic("internal error") }
114 func (f *bitFiler) Sync() error { panic("internal error") }
115
116 func (f *bitFiler) Close() (err error) { return }
117 func (f *bitFiler) Name() string { return fmt.Sprintf("%p.bitfiler", f) }
118 func (f *bitFiler) Size() (int64, error) { return f.size, nil }
119
120 func (f *bitFiler) PunchHole(off, size int64) (err error) {
121 first := off >> bfBits
122 if off&bfMask != 0 {
123 first++
124 }
125 off += size - 1
126 last := off >> bfBits
127 if off&bfMask != 0 {
128 last--
129 }
130 if limit := f.size >> bfBits; last > limit {
131 last = limit
132 }
133 f.Lock()
134 for pgI := first; pgI <= last; pgI++ {
135 pg := &bitPage{}
136 pg.flags = allDirtyFlags
137 f.m[pgI] = pg
138 }
139 f.Unlock()
140 return
141 }
142
143 func (f *bitFiler) ReadAt(b []byte, off int64) (n int, err error) {
144 avail := f.size - off
145 pgI := off >> bfBits
146 pgO := int(off & bfMask)
147 rem := len(b)
148 if int64(rem) >= avail {
149 rem = int(avail)
150 err = io.EOF
151 }
152 for rem != 0 && avail > 0 {
153 f.Lock()
154 pg := f.m[pgI]
155 if pg == nil {
156 pg = &bitPage{}
157 if f.parent != nil {
158 _, err = f.parent.ReadAt(pg.data[:], off&^bfMask)
159 if err != nil && !fileutil.IsEOF(err) {
160 f.Unlock()
161 return
162 }
163
164 err = nil
165 }
166 f.m[pgI] = pg
167 }
168 f.Unlock()
169 nc := copy(b[:mathutil.Min(rem, bfSize)], pg.data[pgO:])
170 pgI++
171 pgO = 0
172 rem -= nc
173 n += nc
174 b = b[nc:]
175 off += int64(nc)
176 }
177 return
178 }
179
180 func (f *bitFiler) Truncate(size int64) (err error) {
181 f.Lock()
182 defer f.Unlock()
183 switch {
184 case size < 0:
185 return &ErrINVAL{"Truncate size", size}
186 case size == 0:
187 f.m = bitFilerMap{}
188 f.size = 0
189 return
190 }
191
192 first := size >> bfBits
193 if size&bfMask != 0 {
194 first++
195 }
196 last := f.size >> bfBits
197 if f.size&bfMask != 0 {
198 last++
199 }
200 for ; first < last; first++ {
201 delete(f.m, first)
202 }
203
204 f.size = size
205 return
206 }
207
208 func (f *bitFiler) WriteAt(b []byte, off int64) (n int, err error) {
209 off0 := off
210 pgI := off >> bfBits
211 pgO := int(off & bfMask)
212 n = len(b)
213 rem := n
214 var nc int
215 for rem != 0 {
216 f.Lock()
217 pg := f.m[pgI]
218 if pg == nil {
219 pg = &bitPage{}
220 if f.parent != nil {
221 _, err = f.parent.ReadAt(pg.data[:], off&^bfMask)
222 if err != nil && !fileutil.IsEOF(err) {
223 f.Unlock()
224 return
225 }
226
227 err = nil
228 }
229 f.m[pgI] = pg
230 }
231 f.Unlock()
232 nc = copy(pg.data[pgO:], b)
233 pgI++
234 pg.dirty = true
235 for i := pgO; i < pgO+nc; i++ {
236 pg.flags[i>>3] |= bitmask[i&7]
237 }
238 pgO = 0
239 rem -= nc
240 b = b[nc:]
241 off += int64(nc)
242 }
243 f.size = mathutil.MaxInt64(f.size, off0+int64(n))
244 return
245 }
246
247 func (f *bitFiler) link() {
248 for pgI, pg := range f.m {
249 nx, ok := f.m[pgI+1]
250 if !ok || !nx.dirty {
251 continue
252 }
253
254 nx.prev, pg.next = pg, nx
255 }
256 }
257
258 func (f *bitFiler) dumpDirty(w io.WriterAt) (nwr int, err error) {
259 f.Lock()
260 defer f.Unlock()
261 f.link()
262 for pgI, pg := range f.m {
263 if !pg.dirty {
264 continue
265 }
266
267 for pg.prev != nil && pg.prev.dirty {
268 pg = pg.prev
269 pgI--
270 }
271
272 for pg != nil && pg.dirty {
273 last := false
274 var off int64
275 first := -1
276 for i := 0; i < bfSize; i++ {
277 flag := pg.flags[i>>3]&bitmask[i&7] != 0
278 switch {
279 case flag && !last: // Leading edge detected
280 off = pgI<<bfBits + int64(i)
281 first = i
282 case !flag && last: // Trailing edge detected
283 n, err := w.WriteAt(pg.data[first:i], off)
284 if n != i-first {
285 return 0, err
286 }
287 first = -1
288 nwr++
289 }
290
291 last = flag
292 }
293 if first >= 0 {
294 i := bfSize
295 n, err := w.WriteAt(pg.data[first:i], off)
296 if n != i-first {
297 return 0, err
298 }
299
300 nwr++
301 }
302
303 pg.dirty = false
304 pg = pg.next
305 pgI++
306 }
307 }
308 return
309 }
310
311 // RollbackFiler is a Filer implementing structural transaction handling.
312 // Structural transactions should be small and short lived because all non
313 // committed data are held in memory until committed or discarded by a
314 // Rollback.
315 //
316 // While using RollbackFiler, every intended update of the wrapped Filler, by
317 // WriteAt, Truncate or PunchHole, _must_ be made within a transaction.
318 // Attempts to do it outside of a transaction will return ErrPERM. OTOH,
319 // invoking ReadAt outside of a transaction is not a problem.
320 //
321 // No nested transactions: All updates within a transaction are held in memory.
322 // On a matching EndUpdate the updates held in memory are actually written to
323 // the wrapped Filer.
324 //
325 // Nested transactions: Correct data will be seen from RollbackFiler when any
326 // level of a nested transaction is rollbacked. The actual writing to the
327 // wrapped Filer happens only when the outer most transaction nesting level is
328 // closed.
329 //
330 // Invoking Rollback is an alternative to EndUpdate. It discards all changes
331 // made at the current transaction level and returns the "state" (possibly not
332 // yet persisted) of the Filer to what it was before the corresponding
333 // BeginUpdate.
334 //
335 // During an open transaction, all reads (using ReadAt) are "dirty" reads,
336 // seeing the uncommitted changes made to the Filer's data.
337 //
338 // Lldb databases should be based upon a RollbackFiler.
339 //
340 // With a wrapped MemFiler one gets transactional memory. With, for example a
341 // wrapped disk based SimpleFileFiler it protects against at least some HW
342 // errors - if Rollback is properly invoked on such failures and/or if there's
343 // some WAL or 2PC or whatever other safe mechanism based recovery procedure
344 // used by the client.
345 //
346 // The "real" writes to the wrapped Filer (or WAL instead) go through the
347 // writerAt supplied to NewRollbackFiler.
348 //
349 // List of functions/methods which are recommended to be wrapped in a
350 // BeginUpdate/EndUpdate structural transaction:
351 //
352 // Allocator.Alloc
353 // Allocator.Free
354 // Allocator.Realloc
355 //
356 // CreateBTree
357 // RemoveBTree
358 // BTree.Clear
359 // BTree.Delete
360 // BTree.DeleteAny
361 // BTree.Clear
362 // BTree.Extract
363 // BTree.Get (it can mutate the DB)
364 // BTree.Put
365 // BTree.Set
366 //
367 // NOTE: RollbackFiler is a generic solution intended to wrap Filers provided
368 // by this package which do not implement any of the transactional methods.
369 // RollbackFiler thus _does not_ invoke any of the transactional methods of its
370 // wrapped Filer.
371 //
372 // RollbackFiler is safe for concurrent use by multiple goroutines.
373 type RollbackFiler struct {
374 mu sync.RWMutex
375 inCallback bool
376 inCallbackMu sync.RWMutex
377 bitFiler *bitFiler
378 checkpoint func(int64) error
379 closed bool
380 f Filer
381 parent Filer
382 tlevel int // transaction nesting level, 0 == not in transaction
383 writerAt io.WriterAt
384
385 // afterRollback, if not nil, is called after performing Rollback
386 // without errros.
387 afterRollback func() error
388 }
389
390 // NewRollbackFiler returns a RollbackFiler wrapping f.
391 //
392 // The checkpoint parameter
393 //
394 // The checkpoint function is called after closing (by EndUpdate) the upper
395 // most level open transaction if all calls of writerAt were successful and the
396 // DB (or eg. a WAL) is thus now in a consistent state (virtually, in the ideal
397 // world with no write caches, no HW failures, no process crashes, ...).
398 //
399 // NOTE: In, for example, a 2PC it is necessary to reflect also the sz
400 // parameter as the new file size (as in the parameter to Truncate). All
401 // changes were successfully written already by writerAt before invoking
402 // checkpoint.
403 //
404 // The writerAt parameter
405 //
406 // The writerAt interface is used to commit the updates of the wrapped Filer.
407 // If any invocation of writerAt fails then a non nil error will be returned
408 // from EndUpdate and checkpoint will _not_ ne called. Neither is necessary to
409 // call Rollback. The rule of thumb: The [structural] transaction [level] is
410 // closed by invoking exactly once one of EndUpdate _or_ Rollback.
411 //
412 // It is presumed that writerAt uses WAL or 2PC or whatever other safe
413 // mechanism to physically commit the updates.
414 //
415 // Updates performed by invocations of writerAt are byte-precise, but not
416 // necessarily maximum possible length precise. IOW, for example an update
417 // crossing page boundaries may be performed by more than one writerAt
418 // invocation. No offset sorting is performed. This may change if it proves
419 // to be a problem. Such change would be considered backward compatible.
420 //
421 // NOTE: Using RollbackFiler, but failing to ever invoke a matching "closing"
422 // EndUpdate after an "opening" BeginUpdate means neither writerAt or
423 // checkpoint will ever get called - with all the possible data loss
424 // consequences.
425 func NewRollbackFiler(f Filer, checkpoint func(sz int64) error, writerAt io.WriterAt) (r *RollbackFiler, err error) {
426 if f == nil || checkpoint == nil || writerAt == nil {
427 return nil, &ErrINVAL{Src: "lldb.NewRollbackFiler, nil argument"}
428 }
429
430 return &RollbackFiler{
431 checkpoint: checkpoint,
432 f: f,
433 writerAt: writerAt,
434 }, nil
435 }
436
437 // Implements Filer.
438 func (r *RollbackFiler) BeginUpdate() (err error) {
439 r.mu.Lock()
440 defer r.mu.Unlock()
441
442 parent := r.f
443 if r.tlevel != 0 {
444 parent = r.bitFiler
445 }
446 r.bitFiler, err = newBitFiler(parent)
447 if err != nil {
448 return
449 }
450
451 r.tlevel++
452 return
453 }
454
455 // Implements Filer.
456 //
457 // Close will return an error if not invoked at nesting level 0. However, to
458 // allow emergency closing from eg. a signal handler; if Close is invoked
459 // within an open transaction(s), it rollbacks any non committed open
460 // transactions and performs the Close operation.
461 //
462 // IOW: Regardless of the transaction nesting level the Close is always
463 // performed but any uncommitted transaction data are lost.
464 func (r *RollbackFiler) Close() (err error) {
465 r.mu.Lock()
466 defer r.mu.Unlock()
467
468 if r.closed {
469 return &ErrPERM{r.f.Name() + ": Already closed"}
470 }
471
472 r.closed = true
473 if err = r.f.Close(); err != nil {
474 return
475 }
476
477 if r.tlevel != 0 {
478 err = &ErrPERM{r.f.Name() + ": Close inside an open transaction"}
479 }
480
481 return
482 }
483
484 // Implements Filer.
485 func (r *RollbackFiler) EndUpdate() (err error) {
486 r.mu.Lock()
487 defer r.mu.Unlock()
488
489 if r.tlevel == 0 {
490 return &ErrPERM{r.f.Name() + " : EndUpdate outside of a transaction"}
491 }
492
493 sz, err := r.size() // Cannot call .Size() -> deadlock
494 if err != nil {
495 return
496 }
497
498 r.tlevel--
499 bf := r.bitFiler
500 parent := bf.parent
501 w := r.writerAt
502 if r.tlevel != 0 {
503 w = parent
504 }
505 nwr, err := bf.dumpDirty(w)
506 if err != nil {
507 return
508 }
509
510 switch {
511 case r.tlevel == 0:
512 r.bitFiler = nil
513 if nwr == 0 {
514 return
515 }
516
517 return r.checkpoint(sz)
518 default:
519 r.bitFiler = parent.(*bitFiler)
520 sz, _ := bf.Size() // bitFiler.Size() never returns err != nil
521 return parent.Truncate(sz)
522 }
523 }
524
525 // Implements Filer.
526 func (r *RollbackFiler) Name() string {
527 r.mu.RLock()
528 defer r.mu.RUnlock()
529
530 return r.f.Name()
531 }
532
533 // Implements Filer.
534 func (r *RollbackFiler) PunchHole(off, size int64) error {
535 r.mu.Lock()
536 defer r.mu.Unlock()
537
538 if r.tlevel == 0 {
539 return &ErrPERM{r.f.Name() + ": PunchHole outside of a transaction"}
540 }
541
542 if off < 0 {
543 return &ErrINVAL{r.f.Name() + ": PunchHole off", off}
544 }
545
546 if size < 0 || off+size > r.bitFiler.size {
547 return &ErrINVAL{r.f.Name() + ": PunchHole size", size}
548 }
549
550 return r.bitFiler.PunchHole(off, size)
551 }
552
553 // Implements Filer.
554 func (r *RollbackFiler) ReadAt(b []byte, off int64) (n int, err error) {
555 r.inCallbackMu.RLock()
556 defer r.inCallbackMu.RUnlock()
557 if !r.inCallback {
558 r.mu.RLock()
559 defer r.mu.RUnlock()
560 }
561 if r.tlevel == 0 {
562 return r.f.ReadAt(b, off)
563 }
564
565 return r.bitFiler.ReadAt(b, off)
566 }
567
568 // Implements Filer.
569 func (r *RollbackFiler) Rollback() (err error) {
570 r.mu.Lock()
571 defer r.mu.Unlock()
572
573 if r.tlevel == 0 {
574 return &ErrPERM{r.f.Name() + ": Rollback outside of a transaction"}
575 }
576
577 if r.tlevel > 1 {
578 r.bitFiler = r.bitFiler.parent.(*bitFiler)
579 }
580 r.tlevel--
581 if f := r.afterRollback; f != nil {
582 r.inCallbackMu.Lock()
583 r.inCallback = true
584 r.inCallbackMu.Unlock()
585 defer func() {
586 r.inCallbackMu.Lock()
587 r.inCallback = false
588 r.inCallbackMu.Unlock()
589 }()
590 return f()
591 }
592 return
593 }
594
595 func (r *RollbackFiler) size() (sz int64, err error) {
596 if r.tlevel == 0 {
597 return r.f.Size()
598 }
599
600 return r.bitFiler.Size()
601 }
602
603 // Implements Filer.
604 func (r *RollbackFiler) Size() (sz int64, err error) {
605 r.mu.Lock()
606 defer r.mu.Unlock()
607
608 return r.size()
609 }
610
611 // Implements Filer.
612 func (r *RollbackFiler) Sync() error {
613 r.mu.Lock()
614 defer r.mu.Unlock()
615
616 return r.f.Sync()
617 }
618
619 // Implements Filer.
620 func (r *RollbackFiler) Truncate(size int64) error {
621 r.mu.Lock()
622 defer r.mu.Unlock()
623
624 if r.tlevel == 0 {
625 return &ErrPERM{r.f.Name() + ": Truncate outside of a transaction"}
626 }
627
628 return r.bitFiler.Truncate(size)
629 }
630
631 // Implements Filer.
632 func (r *RollbackFiler) WriteAt(b []byte, off int64) (n int, err error) {
633 r.mu.Lock()
634 defer r.mu.Unlock()
635
636 if r.tlevel == 0 {
637 return 0, &ErrPERM{r.f.Name() + ": WriteAt outside of a transaction"}
638 }
639
640 return r.bitFiler.WriteAt(b, off)
641 }
0 // Copyright 2014 The lldb Authors. All rights reserved.
1 // Use of this source code is governed by a BSD-style
2 // license that can be found in the LICENSE file.
3
4 package lldb
5
6 import (
7 "bytes"
8 "encoding/hex"
9 "fmt"
10 "io"
11 "math/rand"
12 "testing"
13
14 "github.com/cznic/fileutil"
15 "github.com/cznic/mathutil"
16 )
17
18 func (f *bitFiler) dump(w io.Writer) {
19 fmt.Fprintf(w, "bitFiler @ %p, size: %d(%#x)\n", f, f.size, f.size)
20 for k, v := range f.m {
21 fmt.Fprintf(w, "bitPage @ %p: pgI %d(%#x): %#v\n", v, k, k, *v)
22 }
23 }
24
25 func filerBytes(f Filer) []byte {
26 sz, err := f.Size()
27 if err != nil {
28 panic(err)
29 }
30
31 b := make([]byte, int(sz))
32 n, err := f.ReadAt(b, 0)
33 if n != len(b) {
34 panic(fmt.Errorf("sz %d n %d err %v", sz, n, err))
35 }
36
37 return b
38 }
39
40 func cmpFilerBytes(t *testing.T, fg, fe Filer) {
41 g, e := filerBytes(fg), filerBytes(fe)
42 if !bytes.Equal(g, e) {
43 t.Fatalf("Filer content doesn't match: got\n%sexp:\n%s", hex.Dump(g), hex.Dump(e))
44 }
45 }
46
47 func TestRollbackFiler0(t *testing.T) {
48 var r *RollbackFiler
49 f, g := NewMemFiler(), NewMemFiler()
50
51 checkpoint := func(sz int64) (err error) {
52 return f.Truncate(sz)
53 }
54
55 r, err := NewRollbackFiler(f, checkpoint, f)
56 if err != nil {
57 t.Fatal(err)
58 }
59
60 if err = r.BeginUpdate(); err != nil {
61 t.Fatal(err)
62 }
63
64 if err = r.EndUpdate(); err != nil {
65 t.Fatal(err)
66 }
67
68 cmpFilerBytes(t, f, g)
69 }
70
71 func TestRollbackFiler1(t *testing.T) {
72 const (
73 N = 1e6
74 O = 1234
75 )
76
77 var r *RollbackFiler
78 f, g := NewMemFiler(), NewMemFiler()
79
80 checkpoint := func(sz int64) (err error) {
81 return f.Truncate(sz)
82 }
83
84 r, err := NewRollbackFiler(f, checkpoint, f)
85 if err != nil {
86 t.Fatal(err)
87 }
88
89 if err = r.BeginUpdate(); err != nil {
90 t.Fatal(err)
91 }
92
93 rng := rand.New(rand.NewSource(42))
94 b := make([]byte, N)
95 for i := range b {
96 b[i] = byte(rng.Int())
97 }
98
99 if _, err = g.WriteAt(b, O); err != nil {
100 t.Fatal(err)
101 }
102
103 if _, err = r.WriteAt(b, O); err != nil {
104 t.Fatal(err)
105 }
106
107 b = filerBytes(f)
108 if n := len(b); n != 0 {
109 t.Fatal(n)
110 }
111
112 if err = r.EndUpdate(); err != nil {
113 t.Fatal(err)
114 }
115
116 cmpFilerBytes(t, f, g)
117 }
118
119 func TestRollbackFiler2(t *testing.T) {
120 const (
121 N = 1e6
122 O = 1234
123 )
124
125 var r *RollbackFiler
126 f, g := NewMemFiler(), NewMemFiler()
127
128 checkpoint := func(sz int64) (err error) {
129 return f.Truncate(sz)
130 }
131
132 r, err := NewRollbackFiler(f, checkpoint, f)
133 if err != nil {
134 t.Fatal(err)
135 }
136
137 if err = r.BeginUpdate(); err != nil {
138 t.Fatal(err)
139 }
140
141 rng := rand.New(rand.NewSource(42))
142 b := make([]byte, N)
143 for i := range b {
144 b[i] = byte(rng.Int())
145 }
146
147 if _, err = r.WriteAt(b, O); err != nil {
148 t.Fatal(err)
149 }
150
151 b = filerBytes(f)
152 if n := len(b); n != 0 {
153 t.Fatal(n)
154 }
155
156 if err = r.Rollback(); err != nil {
157 t.Fatal(err)
158 }
159
160 cmpFilerBytes(t, f, g)
161 }
162
163 func rndBytes(rng *rand.Rand, n int) []byte {
164 r := make([]byte, n)
165 for i := range r {
166 r[i] = byte(rng.Int())
167 }
168 return r
169 }
170
171 func TestRollbackFiler3(t *testing.T) {
172 var r *RollbackFiler
173 f := NewMemFiler()
174
175 checkpoint := func(sz int64) (err error) {
176 return f.Truncate(sz)
177 }
178
179 r, err := NewRollbackFiler(f, checkpoint, f)
180 if err != nil {
181 t.Fatal(err)
182 }
183
184 n, err := r.ReadAt([]byte{0}, 0)
185 if n != 0 || !fileutil.IsEOF(err) {
186 t.Fatal(n, err)
187 }
188
189 n, err = r.ReadAt([]byte{0}, 1e6)
190 if n != 0 || !fileutil.IsEOF(err) {
191 t.Fatal(n, err)
192 }
193
194 if err = r.BeginUpdate(); err != nil { // BeginUpdate: 0 -> 1
195 t.Fatal(err)
196 }
197
198 rng := rand.New(rand.NewSource(42))
199
200 buf := rndBytes(rng, 100)
201 if n, err := r.WriteAt(buf, 1e6); n != 100 || err != nil {
202 t.Fatal(err)
203 }
204
205 buf = make([]byte, 100)
206 if n, err := r.ReadAt(buf, 1e6-200); n != 100 || err != nil {
207 t.Fatal(err)
208 }
209
210 for i, v := range buf {
211 if v != 0 {
212 t.Fatal(i, v)
213 }
214 }
215
216 if err := r.Truncate(1e5); err != nil {
217 t.Fatal(err)
218 }
219
220 if err = r.BeginUpdate(); err != nil { // BeginUpdate: 1 -> 2
221 t.Fatal(err)
222 }
223
224 if n, err := r.ReadAt(buf, 1e6); n != 0 || err == nil {
225 t.Fatal(n, err)
226 }
227
228 if err := r.Truncate(2e6); err != nil {
229 t.Fatal(err)
230 }
231
232 if err = r.BeginUpdate(); err != nil { // BeginUpdate: 2 -> 3
233 t.Fatal(err)
234 }
235
236 if n, err := r.ReadAt(buf, 1e6); n == 0 || err != nil {
237 t.Fatal(n, err)
238 }
239
240 for i, v := range buf {
241 if v != 0 {
242 t.Fatal(i, v)
243 }
244 }
245 }
246
247 func TestRollbackFiler4(t *testing.T) {
248 const (
249 maxSize = 1e6
250 maxChange = maxSize/100 + 4
251 maxChanges = 10
252 maxNest = 3
253 )
254
255 var r *RollbackFiler
256 f := NewMemFiler()
257
258 checkpoint := func(sz int64) (err error) {
259 return f.Truncate(sz)
260 }
261
262 r, err := NewRollbackFiler(f, checkpoint, f)
263 if err != nil {
264 t.Fatal(err)
265 }
266
267 rng := rand.New(rand.NewSource(42))
268
269 ref := make([]byte, 2*maxSize)
270 for i := range ref {
271 ref[i] = byte(rng.Int())
272 }
273
274 var finalSize int
275
276 var fn func(int, int, []byte) (int, []byte)
277 fn = func(nest, inSize int, in []byte) (outSize int, out []byte) {
278 defer func() {
279 for i := outSize; i < len(out); i++ {
280 out[i] = 0
281 }
282 finalSize = mathutil.Max(finalSize, outSize)
283 }()
284
285 out = make([]byte, len(in), 2*maxSize)
286 copy(out, in)
287 if err := r.BeginUpdate(); err != nil {
288 t.Fatal(err)
289 }
290
291 for i := 0; i < maxChanges; i++ {
292 changeLen := rng.Intn(maxChange) + 4
293 changeOff := rng.Intn(maxSize * 3 / 2)
294 b := make([]byte, changeLen)
295 for i := range b {
296 b[i] = byte(rng.Int())
297 }
298 if n, err := r.WriteAt(b, int64(changeOff)); n != len(b) || err != nil {
299 t.Fatal(n, len(b), err)
300 }
301 }
302
303 if err := r.Rollback(); err != nil {
304 t.Fatal(err)
305 }
306
307 if err := r.BeginUpdate(); err != nil {
308 t.Fatal(err)
309 }
310
311 for i := 0; i < maxChanges; i++ {
312 changeLen := rng.Intn(maxChange) + 4
313 changeOff := rng.Intn(maxSize * 3 / 2)
314 b := make([]byte, changeLen)
315 for i := range b {
316 b[i] = byte(rng.Int())
317 }
318 if n, err := r.WriteAt(b, int64(changeOff)); n != len(b) || err != nil {
319 t.Fatal(n, len(b), err)
320 }
321 copy(out[changeOff:], b)
322 copy(ref[changeOff:], b)
323 }
324
325 newSize := rng.Intn(maxSize*3/2) + 4
326 if nest == maxNest {
327 if err := r.EndUpdate(); err != nil {
328 t.Fatal(err)
329 }
330
331 return newSize, out
332 }
333
334 outSize, out = fn(nest+1, newSize, out)
335 if err := r.EndUpdate(); err != nil {
336 t.Fatal(err)
337 }
338
339 return
340 }
341
342 sz, result := fn(0, maxSize, ref)
343 if g, e := sz, finalSize; g != e {
344 t.Fatal(err)
345 }
346
347 g, e := result[:sz], ref[:sz]
348 if !bytes.Equal(g, e) {
349 if len(g) == len(e) {
350 x := make([]byte, len(g))
351 for i := range x {
352 if g[i] != e[i] {
353 x[i] = 'X'
354 }
355 }
356 //t.Logf("Data diff\n%s", hex.Dump(x))
357 }
358 //t.Fatalf("Data don't match: got\n%sexp:\n%s", hex.Dump(g), hex.Dump(e))
359 t.Fatalf("Data don't match")
360 }
361 }
362
363 func BenchmarkRollbackFiler(b *testing.B) {
364 rng := rand.New(rand.NewSource(42))
365 type t struct {
366 off int64
367 b []byte
368 }
369 a := []t{}
370 for rem := b.N; rem > 0; {
371 off := rng.Int63()
372 n := mathutil.Min(rng.Intn(1e3)+1, rem)
373 a = append(a, t{off, rndBytes(rng, n)})
374 rem -= n
375 }
376
377 var r *RollbackFiler
378 f := NewMemFiler()
379
380 checkpoint := func(sz int64) (err error) {
381 return f.Truncate(sz)
382 }
383
384 r, err := NewRollbackFiler(f, checkpoint, f)
385 if err != nil {
386 b.Fatal(err)
387 }
388
389 if err := r.BeginUpdate(); err != nil {
390 b.Fatal(err)
391 }
392
393 b.ResetTimer()
394 for _, v := range a {
395 if _, err := r.WriteAt(v.b, v.off); err != nil {
396 b.Fatal(err)
397 }
398 }
399 }