1// Copyright (c) 2014 Couchbase, Inc. 2// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 3// except in compliance with the License. You may obtain a copy of the License at 4// http://www.apache.org/licenses/LICENSE-2.0 5// Unless required by applicable law or agreed to in writing, software distributed under the 6// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 7// either express or implied. See the License for the specific language governing permissions 8// and limitations under the License. 9 10package segment 11 12import ( 13 "bufio" 14 "bytes" 15 "reflect" 16 "strings" 17 "testing" 18) 19 20func TestAdhocSegmentsWithType(t *testing.T) { 21 22 tests := []struct { 23 input []byte 24 output [][]byte 25 outputStrings []string 26 outputTypes []int 27 }{ 28 { 29 input: []byte("Now is the.\n End."), 30 output: [][]byte{ 31 []byte("Now"), 32 []byte(" "), 33 []byte(" "), 34 []byte("is"), 35 []byte(" "), 36 []byte("the"), 37 []byte("."), 38 []byte("\n"), 39 []byte(" "), 40 []byte("End"), 41 []byte("."), 42 }, 43 outputStrings: []string{ 44 "Now", 45 " ", 46 " ", 47 "is", 48 " ", 49 "the", 50 ".", 51 "\n", 52 " ", 53 "End", 54 ".", 55 }, 56 outputTypes: []int{ 57 Letter, 58 None, 59 None, 60 Letter, 61 None, 62 Letter, 63 None, 64 None, 65 None, 66 Letter, 67 None, 68 }, 69 }, 70 { 71 input: []byte("3.5"), 72 output: [][]byte{ 73 []byte("3.5"), 74 }, 75 outputStrings: []string{ 76 "3.5", 77 }, 78 outputTypes: []int{ 79 Number, 80 }, 81 }, 82 { 83 input: []byte("cat3.5"), 84 output: [][]byte{ 85 []byte("cat3.5"), 86 }, 87 outputStrings: []string{ 88 "cat3.5", 89 }, 90 outputTypes: []int{ 91 Letter, 92 }, 93 }, 94 { 95 input: []byte("c"), 96 output: [][]byte{ 97 []byte("c"), 98 }, 99 outputStrings: []string{ 100 "c", 101 }, 102 outputTypes: []int{ 103 Letter, 104 }, 105 }, 106 { 107 input: []byte("こんにちは世界"), 108 output: [][]byte{ 109 []byte("こ"), 110 []byte("ん"), 111 []byte("に"), 112 []byte("ち"), 113 []byte("は"), 114 []byte("世"), 115 []byte("界"), 116 }, 117 outputStrings: []string{ 118 "こ", 119 "ん", 120 "に", 121 "ち", 122 "は", 123 "世", 124 "界", 125 }, 126 outputTypes: []int{ 127 Ideo, 128 Ideo, 129 Ideo, 130 Ideo, 131 Ideo, 132 Ideo, 133 Ideo, 134 }, 135 }, 136 { 137 input: []byte("你好世界"), 138 output: [][]byte{ 139 []byte("你"), 140 []byte("好"), 141 []byte("世"), 142 []byte("界"), 143 }, 144 outputStrings: []string{ 145 "你", 146 "好", 147 "世", 148 "界", 149 }, 150 outputTypes: []int{ 151 Ideo, 152 Ideo, 153 Ideo, 154 Ideo, 155 }, 156 }, 157 { 158 input: []byte("サッカ"), 159 output: [][]byte{ 160 []byte("サッカ"), 161 }, 162 outputStrings: []string{ 163 "サッカ", 164 }, 165 outputTypes: []int{ 166 Ideo, 167 }, 168 }, 169 // test for wb7b/wb7c 170 { 171 input: []byte(`א"א`), 172 output: [][]byte{ 173 []byte(`א"א`), 174 }, 175 outputStrings: []string{ 176 `א"א`, 177 }, 178 outputTypes: []int{ 179 Letter, 180 }, 181 }, 182 } 183 184 for _, test := range tests { 185 rv := make([][]byte, 0) 186 rvstrings := make([]string, 0) 187 rvtypes := make([]int, 0) 188 segmenter := NewWordSegmenter(bytes.NewReader(test.input)) 189 // Set the split function for the scanning operation. 190 for segmenter.Segment() { 191 rv = append(rv, segmenter.Bytes()) 192 rvstrings = append(rvstrings, segmenter.Text()) 193 rvtypes = append(rvtypes, segmenter.Type()) 194 } 195 if err := segmenter.Err(); err != nil { 196 t.Fatal(err) 197 } 198 if !reflect.DeepEqual(rv, test.output) { 199 t.Fatalf("expected:\n%#v\ngot:\n%#v\nfor: '%s'", test.output, rv, test.input) 200 } 201 if !reflect.DeepEqual(rvstrings, test.outputStrings) { 202 t.Fatalf("expected:\n%#v\ngot:\n%#v\nfor: '%s'", test.outputStrings, rvstrings, test.input) 203 } 204 if !reflect.DeepEqual(rvtypes, test.outputTypes) { 205 t.Fatalf("expeced:\n%#v\ngot:\n%#v\nfor: '%s'", test.outputTypes, rvtypes, test.input) 206 } 207 } 208 209 // run same tests again with direct 210 for _, test := range tests { 211 rv := make([][]byte, 0) 212 rvstrings := make([]string, 0) 213 rvtypes := make([]int, 0) 214 segmenter := NewWordSegmenterDirect(test.input) 215 // Set the split function for the scanning operation. 216 for segmenter.Segment() { 217 rv = append(rv, segmenter.Bytes()) 218 rvstrings = append(rvstrings, segmenter.Text()) 219 rvtypes = append(rvtypes, segmenter.Type()) 220 } 221 if err := segmenter.Err(); err != nil { 222 t.Fatal(err) 223 } 224 if !reflect.DeepEqual(rv, test.output) { 225 t.Fatalf("expected:\n%#v\ngot:\n%#v\nfor: '%s'", test.output, rv, test.input) 226 } 227 if !reflect.DeepEqual(rvstrings, test.outputStrings) { 228 t.Fatalf("expected:\n%#v\ngot:\n%#v\nfor: '%s'", test.outputStrings, rvstrings, test.input) 229 } 230 if !reflect.DeepEqual(rvtypes, test.outputTypes) { 231 t.Fatalf("expeced:\n%#v\ngot:\n%#v\nfor: '%s'", test.outputTypes, rvtypes, test.input) 232 } 233 } 234 235} 236 237func TestUnicodeSegments(t *testing.T) { 238 239 for _, test := range unicodeWordTests { 240 rv := make([][]byte, 0) 241 scanner := bufio.NewScanner(bytes.NewReader(test.input)) 242 // Set the split function for the scanning operation. 243 scanner.Split(SplitWords) 244 for scanner.Scan() { 245 rv = append(rv, scanner.Bytes()) 246 } 247 if err := scanner.Err(); err != nil { 248 t.Fatal(err) 249 } 250 if !reflect.DeepEqual(rv, test.output) { 251 t.Fatalf("expected:\n%#v\ngot:\n%#v\nfor: '%s' comment: %s", test.output, rv, test.input, test.comment) 252 } 253 } 254} 255 256func TestUnicodeSegmentsSlowReader(t *testing.T) { 257 258 for i, test := range unicodeWordTests { 259 rv := make([][]byte, 0) 260 segmenter := NewWordSegmenter(&slowReader{1, bytes.NewReader(test.input)}) 261 for segmenter.Segment() { 262 rv = append(rv, segmenter.Bytes()) 263 } 264 if err := segmenter.Err(); err != nil { 265 t.Fatal(err) 266 } 267 if !reflect.DeepEqual(rv, test.output) { 268 t.Fatalf("expected:\n%#v\ngot:\n%#v\nfor: %d '%s' comment: %s", test.output, rv, i, test.input, test.comment) 269 } 270 } 271} 272 273func TestWordSegmentLongInputSlowReader(t *testing.T) { 274 // Read the data. 275 text := bytes.Repeat([]byte("abcdefghijklmnop"), 26) 276 buf := strings.NewReader(string(text) + " cat") 277 s := NewSegmenter(&slowReader{1, buf}) 278 s.MaxTokenSize(6144) 279 for s.Segment() { 280 } 281 err := s.Err() 282 if err != nil { 283 t.Fatalf("unexpected error; got '%s'", err) 284 } 285 finalWord := s.Text() 286 if s.Text() != "cat" { 287 t.Errorf("expected 'cat' got '%s'", finalWord) 288 } 289} 290 291func BenchmarkSplitWords(b *testing.B) { 292 for i := 0; i < b.N; i++ { 293 vals := make([][]byte, 0) 294 scanner := bufio.NewScanner(bytes.NewReader(bleveWikiArticle)) 295 scanner.Split(SplitWords) 296 for scanner.Scan() { 297 vals = append(vals, scanner.Bytes()) 298 } 299 if err := scanner.Err(); err != nil { 300 b.Fatal(err) 301 } 302 if len(vals) != 3465 { 303 b.Fatalf("expected 3465 tokens, got %d", len(vals)) 304 } 305 } 306 307} 308 309func BenchmarkWordSegmenter(b *testing.B) { 310 311 for i := 0; i < b.N; i++ { 312 vals := make([][]byte, 0) 313 types := make([]int, 0) 314 segmenter := NewWordSegmenter(bytes.NewReader(bleveWikiArticle)) 315 for segmenter.Segment() { 316 vals = append(vals, segmenter.Bytes()) 317 types = append(types, segmenter.Type()) 318 } 319 if err := segmenter.Err(); err != nil { 320 b.Fatal(err) 321 } 322 if vals == nil { 323 b.Fatalf("expected non-nil vals") 324 } 325 if types == nil { 326 b.Fatalf("expected non-nil types") 327 } 328 } 329} 330 331func BenchmarkWordSegmenterDirect(b *testing.B) { 332 333 for i := 0; i < b.N; i++ { 334 vals := make([][]byte, 0) 335 types := make([]int, 0) 336 segmenter := NewWordSegmenterDirect(bleveWikiArticle) 337 for segmenter.Segment() { 338 vals = append(vals, segmenter.Bytes()) 339 types = append(types, segmenter.Type()) 340 } 341 if err := segmenter.Err(); err != nil { 342 b.Fatal(err) 343 } 344 if vals == nil { 345 b.Fatalf("expected non-nil vals") 346 } 347 if types == nil { 348 b.Fatalf("expected non-nil types") 349 } 350 } 351} 352 353func BenchmarkDirect(b *testing.B) { 354 355 for i := 0; i < b.N; i++ { 356 vals := make([][]byte, 0, 10000) 357 types := make([]int, 0, 10000) 358 vals, types, _, err := SegmentWordsDirect(bleveWikiArticle, vals, types) 359 if err != nil { 360 b.Fatal(err) 361 } 362 if vals == nil { 363 b.Fatalf("expected non-nil vals") 364 } 365 if types == nil { 366 b.Fatalf("expected non-nil types") 367 } 368 } 369} 370 371var bleveWikiArticle = []byte(`Boiling liquid expanding vapor explosion 372From Wikipedia, the free encyclopedia 373See also: Boiler explosion and Steam explosion 374 375Flames subsequent to a flammable liquid BLEVE from a tanker. BLEVEs do not necessarily involve fire. 376 377This article's tone or style may not reflect the encyclopedic tone used on Wikipedia. See Wikipedia's guide to writing better articles for suggestions. (July 2013) 378A boiling liquid expanding vapor explosion (BLEVE, /ˈblɛviː/ blev-ee) is an explosion caused by the rupture of a vessel containing a pressurized liquid above its boiling point.[1] 379Contents [hide] 3801 Mechanism 3811.1 Water example 3821.2 BLEVEs without chemical reactions 3832 Fires 3843 Incidents 3854 Safety measures 3865 See also 3876 References 3887 External links 389Mechanism[edit] 390 391This section needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed. (July 2013) 392There are three characteristics of liquids which are relevant to the discussion of a BLEVE: 393If a liquid in a sealed container is boiled, the pressure inside the container increases. As the liquid changes to a gas it expands - this expansion in a vented container would cause the gas and liquid to take up more space. In a sealed container the gas and liquid are not able to take up more space and so the pressure rises. Pressurized vessels containing liquids can reach an equilibrium where the liquid stops boiling and the pressure stops rising. This occurs when no more heat is being added to the system (either because it has reached ambient temperature or has had a heat source removed). 394The boiling temperature of a liquid is dependent on pressure - high pressures will yield high boiling temperatures, and low pressures will yield low boiling temperatures. A common simple experiment is to place a cup of water in a vacuum chamber, and then reduce the pressure in the chamber until the water boils. By reducing the pressure the water will boil even at room temperature. This works both ways - if the pressure is increased beyond normal atmospheric pressures, the boiling of hot water could be suppressed far beyond normal temperatures. The cooling system of a modern internal combustion engine is a real-world example. 395When a liquid boils it turns into a gas. The resulting gas takes up far more space than the liquid did. 396Typically, a BLEVE starts with a container of liquid which is held above its normal, atmospheric-pressure boiling temperature. Many substances normally stored as liquids, such as CO2, propane, and other similar industrial gases have boiling temperatures, at atmospheric pressure, far below room temperature. In the case of water, a BLEVE could occur if a pressurized chamber of water is heated far beyond the standard 100 °C (212 °F). That container, because the boiling water pressurizes it, is capable of holding liquid water at very high temperatures. 397If the pressurized vessel, containing liquid at high temperature (which may be room temperature, depending on the substance) ruptures, the pressure which prevents the liquid from boiling is lost. If the rupture is catastrophic, where the vessel is immediately incapable of holding any pressure at all, then there suddenly exists a large mass of liquid which is at very high temperature and very low pressure. This causes the entire volume of liquid to instantaneously boil, which in turn causes an extremely rapid expansion. Depending on temperatures, pressures and the substance involved, that expansion may be so rapid that it can be classified as an explosion, fully capable of inflicting severe damage on its surroundings. 398Water example[edit] 399Imagine, for example, a tank of pressurized liquid water held at 204.4 °C (400 °F). This tank would normally be pressurized to 1.7 MPa (250 psi) above atmospheric ("gauge") pressure. If the tank containing the water were to rupture, there would for a slight moment exist a volume of liquid water which would be 400at atmospheric pressure, and 401204.4 °C (400 °F). 402At atmospheric pressure the boiling point of water is 100 °C (212 °F) - liquid water at atmospheric pressure cannot exist at temperatures higher than 100 °C (212 °F). At that moment, the water would boil and turn to vapour explosively, and the 204.4 °C (400 °F) liquid water turned to gas would take up a lot more volume than it did as liquid, causing a vapour explosion. Such explosions can happen when the superheated water of a steam engine escapes through a crack in a boiler, causing a boiler explosion. 403BLEVEs without chemical reactions[edit] 404It is important to note that a BLEVE need not be a chemical explosion—nor does there need to be a fire—however if a flammable substance is subject to a BLEVE it may also be subject to intense heating, either from an external source of heat which may have caused the vessel to rupture in the first place or from an internal source of localized heating such as skin friction. This heating can cause a flammable substance to ignite, adding a secondary explosion caused by the primary BLEVE. While blast effects of any BLEVE can be devastating, a flammable substance such as propane can add significantly to the danger. 405Bleve explosion.svg 406While the term BLEVE is most often used to describe the results of a container of flammable liquid rupturing due to fire, a BLEVE can occur even with a non-flammable substance such as water,[2] liquid nitrogen,[3] liquid helium or other refrigerants or cryogens, and therefore is not usually considered a type of chemical explosion. 407Fires[edit] 408BLEVEs can be caused by an external fire near the storage vessel causing heating of the contents and pressure build-up. While tanks are often designed to withstand great pressure, constant heating can cause the metal to weaken and eventually fail. If the tank is being heated in an area where there is no liquid, it may rupture faster without the liquid to absorb the heat. Gas containers are usually equipped with relief valves that vent off excess pressure, but the tank can still fail if the pressure is not released quickly enough.[1] Relief valves are sized to release pressure fast enough to prevent the pressure from increasing beyond the strength of the vessel, but not so fast as to be the cause of an explosion. An appropriately sized relief valve will allow the liquid inside to boil slowly, maintaining a constant pressure in the vessel until all the liquid has boiled and the vessel empties. 409If the substance involved is flammable, it is likely that the resulting cloud of the substance will ignite after the BLEVE has occurred, forming a fireball and possibly a fuel-air explosion, also termed a vapor cloud explosion (VCE). If the materials are toxic, a large area will be contaminated.[4] 410Incidents[edit] 411The term "BLEVE" was coined by three researchers at Factory Mutual, in the analysis of an accident there in 1957 involving a chemical reactor vessel.[5] 412In August 1959 the Kansas City Fire Department suffered its largest ever loss of life in the line of duty, when a 25,000 gallon (95,000 litre) gas tank exploded during a fire on Southwest Boulevard killing five firefighters. This was the first time BLEVE was used to describe a burning fuel tank.[citation needed] 413Later incidents included the Cheapside Street Whisky Bond Fire in Glasgow, Scotland in 1960; Feyzin, France in 1966; Crescent City, Illinois in 1970; Kingman, Arizona in 1973; a liquid nitrogen tank rupture[6] at Air Products and Chemicals and Mobay Chemical Company at New Martinsville, West Virginia on January 31, 1978 [1];Texas City, Texas in 1978; Murdock, Illinois in 1983; San Juan Ixhuatepec, Mexico City in 1984; and Toronto, Ontario in 2008. 414Safety measures[edit] 415[icon] This section requires expansion. (July 2013) 416Some fire mitigation measures are listed under liquefied petroleum gas. 417See also[edit] 418Boiler explosion 419Expansion ratio 420Explosive boiling or phase explosion 421Rapid phase transition 422Viareggio train derailment 4232008 Toronto explosions 424Gas carriers 425Los Alfaques Disaster 426Lac-Mégantic derailment 427References[edit] 428^ Jump up to: a b Kletz, Trevor (March 1990). Critical Aspects of Safety and Loss Prevention. London: Butterworth–Heinemann. pp. 43–45. ISBN 0-408-04429-2. 429Jump up ^ "Temperature Pressure Relief Valves on Water Heaters: test, inspect, replace, repair guide". Inspect-ny.com. Retrieved 2011-07-12. 430Jump up ^ Liquid nitrogen BLEVE demo 431Jump up ^ "Chemical Process Safety" (PDF). Retrieved 2011-07-12. 432Jump up ^ David F. Peterson, BLEVE: Facts, Risk Factors, and Fallacies, Fire Engineering magazine (2002). 433Jump up ^ "STATE EX REL. VAPOR CORP. v. NARICK". Supreme Court of Appeals of West Virginia. 1984-07-12. Retrieved 2014-03-16. 434External links[edit] 435 Look up boiling liquid expanding vapor explosion in Wiktionary, the free dictionary. 436 Wikimedia Commons has media related to BLEVE. 437BLEVE Demo on YouTube — video of a controlled BLEVE demo 438huge explosions on YouTube — video of propane and isobutane BLEVEs from a train derailment at Murdock, Illinois (3 September 1983) 439Propane BLEVE on YouTube — video of BLEVE from the Toronto propane depot fire 440Moscow Ring Road Accident on YouTube - Dozens of LPG tank BLEVEs after a road accident in Moscow 441Kingman, AZ BLEVE — An account of the 5 July 1973 explosion in Kingman, with photographs 442Propane Tank Explosions — Description of circumstances required to cause a propane tank BLEVE. 443Analysis of BLEVE Events at DOE Sites - Details physics and mathematics of BLEVEs. 444HID - SAFETY REPORT ASSESSMENT GUIDE: Whisky Maturation Warehouses - The liquor is aged in wooden barrels that can suffer BLEVE. 445Categories: ExplosivesFirefightingFireTypes of fireGas technologiesIndustrial fires and explosions`) 446