Loosing data with (GatheringByteChannel) RandomAccessFile.getChannel.write(buffers) - nio

I open raf, get file channel, accumulate some data in buffers then
channel.position(raf.length)
channel.write(buffers)
channel.close
raf.close
I expect that bytes are written into raf at these offsets, which are raf.length + accumulated buffer sizes in the array
0,62,132,195,259,322,392,455,519,589,652,716,779,842,905,968,1031,1093,1155,1225,1287,1350,1414,1477,1541,1611,1674,1737,1801,1863,1927,1989,2059,2123,2193,2256,2319,2382,2452,2516,2586,2648,2711,2774,2837,2900,2962,3025,3089,3152,3216,3286,3348,3412,3482,3544,3614,3684,3754,3818,3882,3952,4022,4092
and ProcMon displays that this is what starts to happen at OS level
"CreateFile","objects.bin","SUCCESS","Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened"
"QueryNetworkOpenInformationFile","objects.bin","SUCCESS","CreationTime: 6.12.2015 20:11:21, LastAccessTime: 8.12.2015 11:03:49, LastWriteTime: 8.12.2015 11:03:49, ChangeTime: 8.12.2015 11:03:49, AllocationSize: 1.01.1601 2:00:00, EndOfFile: 1.01.1601 2:00:00, FileAttributes: ANCI"
"CloseFile","objects.bin","SUCCESS",""
"CreateFile","objects.bin","SUCCESS","Desired Access: Read Attributes, Delete, Disposition: Open, Options: Non-Directory File, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened"
"QueryAttributeTagFile","objects.bin","SUCCESS","Attributes: ANCI, ReparseTag: 0x0"
"SetDispositionInformationFile","objects.bin","SUCCESS","Delete: True"
"CloseFile","objects.bin","SUCCESS",""
"CreateFile","objects.bin","SUCCESS","Desired Access: Generic Read/Write, Disposition: OpenIf, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: N, ShareMode: Read, Write, AllocationSize: 0, OpenResult: Created"
"QueryStandardInformationFile","objects.bin","SUCCESS","AllocationSize: 0, EndOfFile: 0, NumberOfLinks: 1, DeletePending: False, Directory: False"
"WriteFile","objects.bin","SUCCESS","Offset: 0, Length: 62, Priority: Normal"
"WriteFile","objects.bin","SUCCESS","Offset: 62, Length: 70, Priority: Normal"
"WriteFile","objects.bin","SUCCESS","Offset: 132, Length: 63, Priority: Normal"
"WriteFile","objects.bin","SUCCESS","Offset: 195, Length: 64, Priority: Normal"
"WriteFile","objects.bin","SUCCESS","Offset: 259, Length: 63, Priority: Normal"
"WriteFile","objects.bin","SUCCESS","Offset: 322, Length: 70, Priority: Normal"
"WriteFile","objects.bin","SUCCESS","Offset: 392, Length: 63, Priority: Normal"
"WriteFile","objects.bin","SUCCESS","Offset: 455, Length: 64, Priority: Normal"
"WriteFile","objects.bin","SUCCESS","Offset: 519, Length: 70, Priority: Normal"
"WriteFile","objects.bin","SUCCESS","Offset: 589, Length: 63, Priority: Normal"
"WriteFile","objects.bin","SUCCESS","Offset: 652, Length: 64, Priority: Normal"
"WriteFile","objects.bin","SUCCESS","Offset: 716, Length: 63, Priority: Normal"
"WriteFile","objects.bin","SUCCESS","Offset: 779, Length: 63"
"WriteFile","objects.bin","SUCCESS","Offset: 842, Length: 63"
"WriteFile","objects.bin","SUCCESS","Offset: 905, Length: 63"
"WriteFile","objects.bin","SUCCESS","Offset: 968, Length: 63"
"ReadFile","objects.bin","END OF FILE","Offset: 2 452, Length: 2"
"QueryStandardInformationFile","objects.bin","SUCCESS","AllocationSize: 4 096, EndOfFile: 1 031, NumberOfLinks: 1, DeletePending: False, Directory: False"
"WriteFile","objects.bin","SUCCESS","Offset: 1 031, Length: 64"
"WriteFile","objects.bin","SUCCESS","Offset: 1 095, Length: 70"
"WriteFile","objects.bin","SUCCESS","Offset: 1 165, Length: 70"
"WriteFile","objects.bin","SUCCESS","Offset: 1 235, Length: 64"
"WriteFile","objects.bin","SUCCESS","Offset: 1 299, Length: 63"
"WriteFile","objects.bin","SUCCESS","Offset: 1 362, Length: 64"
"WriteFile","objects.bin","SUCCESS","Offset: 1 426, Length: 63"
"WriteFile","objects.bin","SUCCESS","Offset: 1 489, Length: 63"
"WriteFile","objects.bin","SUCCESS","Offset: 1 552, Length: 63"
"WriteFile","objects.bin","SUCCESS","Offset: 1 615, Length: 64"
"WriteFile","objects.bin","SUCCESS","Offset: 1 679, Length: 70"
"WriteFile","objects.bin","SUCCESS","Offset: 1 749, Length: 64"
"WriteFile","objects.bin","SUCCESS","Offset: 1 813, Length: 63"
"WriteFile","objects.bin","SUCCESS","Offset: 1 876, Length: 63"
"WriteFile","objects.bin","SUCCESS","Offset: 1 939, Length: 63"
"WriteFile","objects.bin","SUCCESS","Offset: 2 002, Length: 63"
"CloseFile","objects.bin","SUCCESS",""
As you see, it writes 16 buffers at offsets 0, 62, 132, ... up to 968 and closes the file! Next it opens it again and proceeds at offsets 1031,1095,1165, which come from another session, where I do the same: open raf and fc, and write another series of buffers, which breaks after 16 buffers written again. The second series starts at 1031 where file was closed and where it was a location for 17th buffer from first write. I see nothing about 16 buffer limitation in the jdocs.
Fortunately, fileChannel.force does not help to cure this situation because I do not need my data physically on disk unless system shuts down. I am happy with data flushed into OS cache at fc.write time or when JVM closes down so that it is available next time that I open the file in the same system.
Here is the program to reproduce the bug
object FileChannelFailureDemo extends App {
import java.nio._, java.io._, java.nio.channels._
val raf = new RandomAccessFile("""objects2""", "rw") ; val fc = raf.getChannel
val range = (1 to 20)
val ba = range.map (i => ByteBuffer.wrap(Array.ofDim[Byte](i)))
fc.write(ba.toArray) //> res0: Long = 136
val expectedLength = range.foldLeft(0){case (acc, i) => acc + i}
//> expectedLength : Int = 210
// 1+2+..+20 = 20*21/2 = 210 // epxected len
// 1+2+..+16 = 16*17/2 = 136 // len of file if only 16 buffers written
// assertion here, file size 136 != 210
assert(raf.length == expectedLength , raf.length + " != " + expectedLength)
//> java.lang.AssertionError: assertion failed: 136 != 210
//| at scala.Predef$.assert(Predef.scala:165)
println("succeeded, file size is " + raf.length)
fc.close; raf.close
}
Curiously, but it is not reproduced in that remote machine. I also do not see it if run this short program from console but this code fails assertion executed from Worksheet. It seems to depend on the program state. It can fail or succeed with the same JRE.

Related

how to use array.count in swift for-in loop

I'm a beginner in swift (probably) and I am learning how to use arrays I was trying to make a for-in loop with a loop amount of 1...array.count, but instead I get an error of:
Fatal error: Index out of range Current stack trace: 0
libswiftCore.so 0x00007f0f71f0aea0
swift_reportError + 50 1 libswiftCore.so
0x00007f0f71f7c0c0 swift_stdlib_reportFatalError + 69 2
libswiftCore.so 0x00007f0f71e775d7 +
3347927 3 libswiftCore.so 0x00007f0f71c94d80
fatalErrorMessage(::file:line:flags:) + 19 4 libswiftSwiftOnoneSupport.so 0x00007f0f755c7ad0 specialized
Array.subscript.getter + 85 6 swift
0x00000000004f23c9 + 992201 7 swift
0x00000000004f6a40 + 1010240 8 swift
0x00000000004e62ef + 942831 9 swift
0x00000000004d5093 + 872595 10 swift
0x00000000004d0e4e + 855630 11 swift
0x0000000000473c16 + 474134 12 libc.so.6
0x00007f0f73771ab0 __libc_start_main + 231 13 swift
0x000000000047387a + 473210 Stack dump:
0. Program arguments: /usr/bin/swift -frontend -interpret Forecast.swift -disable-objc-interop -module-name Forecast
/usr/bin/swift[0x4521834] /usr/bin/swift[0x451f48e]
/usr/bin/swift[0x4521c48]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x128a0)[0x7f0f7532b8a0]
/usr/lib/swift/linux/libswiftCore.so(+0x3315d7)[0x7f0f71e775d7]
/usr/lib/swift/linux/libswiftCore.so($ss18_fatalErrorMessage__4file4line5flagss5NeverOs12StaticStringV_A2HSus6UInt32VtF+0x13)[0x7f0f71c94d93]
/usr/lib/swift/linux/libswiftSwiftOnoneSupport.so($sSayxSicigSi_Tg5+0x55)[0x7f0f755c7b25]
[0x7f0f7575d315] /usr/bin/swift[0x4f23c9] /usr/bin/swift[0x4f6a40]
/usr/bin/swift[0x4e62ef] /usr/bin/swift[0x4d5093]
/usr/bin/swift[0x4d0e4e] /usr/bin/swift[0x473c16]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x7f0f73771b97]
/usr/bin/swift[0x47387a]
what do I do? Here is my code, it is for CodeAcademy:
var temperature: [Int] = [66, 68, 72, 76, 80, 82, 85, 85, 84, 82, 81, 78, 74, 73, 72, 71, 70, 69, 68, 65, 63, 62, 61, 63]
// Write your code below 🌴
for i in 1...temperature.count{
print(temperature[i])
}
I presume your goal is to print all the temperature elements. Change
for i in 1...temperature.count {
To
for i in 0..<temperature.count {
Array indexes start at zero and end at one less than the count. The ..< operator handles this nicely. Or, even better, say
for i in temperature.indices {
One more option is to use forEach:
array.forEach { print($0) }
use for i in temperature. this is basic array iteration, keep in mind :D
var temperature: [Int] = [66, 68, 72, 76, 80, 82, 85, 85, 84, 82, 81, 78, 74, 73, 72, 71, 70, 69, 68, 65, 63, 62, 61, 63]
// Write your code below 🌴
for i in 1...temperature.count{
print(temperature[i-1])
}
You are getting this error because temperature[temperature.count] doesn't exist. You need to limit it till temperature[temperature.count-1] and the index should start from 1 instead of 0.
Alternatively
for i in 0...(temperature.count-1){
print(temperature[i])
}

Pearson hash 8-bit implementation is producing very non-uniform values

I am implementing a pearson hash in order to create a lightweight dictionary structure for a C project which requires a table of files names paired with file data - I want the nice constant search property of hash tables. I'm no math expert so I looked up good text hashes and pearson came up, with it being claimed to be effective and having a good distribution. I tested my implementation and found that no matter how I vary the table size or the filename max length, the hash is very inefficient, with for example 18/50 buckets being left empty. I trust wikipedia to not be lying, and yes I am aware I can just download a third party hash table implementation, but I would dearly like to know why my version isn't working.
In the following code, (a function to insert values into the table), "csString" is the filename, the string to be hashed, "cLen" is the length of the string, "pData" is a pointer to some data which is inserted into the table, and "pTable" is the table struct. The initial condition cHash = cLen - csString[0] is somethin I experimentally found to marginally improve uniformity. I should add that I am testing the table with entirely randomised strings (using rand() to generate ascii values) with randomised length between a certain range - this is in order to easily generate and test large amounts of values.
typedef struct StaticStrTable {
unsigned int nRepeats;
unsigned char nBuckets;
unsigned char nMaxCollisions;
void** pBuckets;
} StaticStrTable;
static const char cPerm256[256] = {
227, 117, 238, 33, 25, 165, 107, 226, 132, 88, 84, 68, 217, 237, 228, 58, 52, 147, 46, 197, 191, 119, 211, 0, 218, 139, 196, 153, 170, 77, 175, 22, 193, 83, 66, 182, 151, 99, 11, 144, 104, 233, 166, 34, 177, 14, 194, 51, 30, 121, 102, 49,
222, 210, 199, 122, 235, 72, 13, 156, 38, 145, 137, 78, 65, 176, 94, 163, 95, 59, 92, 114, 243, 204, 224, 43, 185, 168, 244, 203, 28, 124, 248, 105, 10, 87, 115, 161, 138, 223, 108, 192, 6, 186, 101, 16, 39, 134, 123, 200, 190, 195, 178,
164, 9, 251, 245, 73, 162, 71, 7, 239, 62, 69, 209, 159, 3, 45, 247, 19, 174, 149, 61, 57, 146, 234, 189, 15, 202, 89, 111, 207, 31, 127, 215, 198, 231, 4, 181, 154, 64, 125, 24, 93, 152, 37, 116, 160, 113, 169, 255, 44, 36, 70, 225, 79,
250, 12, 229, 230, 76, 167, 118, 232, 142, 212, 98, 82, 252, 130, 23, 29, 236, 86, 240, 32, 90, 67, 126, 8, 133, 85, 20, 63, 47, 150, 135, 100, 103, 173, 184, 48, 143, 42, 54, 129, 242, 18, 187, 106, 254, 53, 120, 205, 155, 216, 219, 172,
21, 253, 5, 221, 40, 27, 2, 179, 74, 17, 55, 183, 56, 50, 110, 201, 109, 249, 128, 112, 75, 220, 214, 140, 246, 213, 136, 148, 97, 35, 241, 60, 188, 180, 206, 80, 91, 96, 157, 81, 171, 141, 131, 158, 1, 208, 26, 41
};
void InsertStaticStrTable(char* csString, unsigned char cLen, void* pData, StaticStrTable* pTable) {
unsigned char cHash = cLen - csString[0];
for (int i = 0; i < cLen; ++i) cHash ^= cPerm256[cHash ^ csString[i]];
unsigned short cTableIndex = cHash % pTable->nBuckets;
long long* pBucket = pTable->pBuckets[cTableIndex];
// Inserts data and records how many collisions there are - it may look weird as the way in which I decided to pack the data into the table buffer is very compact and arbitrary
// It won't affect the hash though, which is the key issue!
for (int i = 0; i < pTable->nMaxCollisions; ++i) {
if (i == 1) {
pTable->nRepeats++;
}
long long* pSlotID = pBucket + (i << 1);
if (pSlotID[0] == 0) {
pSlotID[0] = csString;
pSlotID[1] = pData;
break;
}
}
}
FYI (This is not an answer, I just need the formatting)
These are just single runs from a simulation, YMMV.
distributing 50 elements randomly over 50 bins:
kalender_size=50 nperson = 50
E/cell| Ncell | frac | Nelem | frac |h/cell| hops | Cumhops
----+---------+--------+----------+--------+------+--------+--------
0: 18 (0.360000) 0 (0.000000) 0 0 0
1: 18 (0.360000) 18 (0.360000) 1 18 18
2: 10 (0.200000) 20 (0.400000) 3 30 48
3: 4 (0.080000) 12 (0.240000) 6 24 72
----+---------+--------+----------+--------+------+--------+--------
4: 50 50 1.440000 72
Similarly: distribute 365 persons over a birthday-calendar (ignoring leap days ...):
kalender_size=356 nperson = 356
E/cell| Ncell | frac | Nelem | frac |h/cell| hops | Cumhops
----+---------+--------+----------+--------+------+--------+--------
0: 129 (0.362360) 0 (0.000000) 0 0 0
1: 132 (0.370787) 132 (0.370787) 1 132 132
2: 69 (0.193820) 138 (0.387640) 3 207 339
3: 19 (0.053371) 57 (0.160112) 6 114 453
4: 6 (0.016854) 24 (0.067416) 10 60 513
5: 1 (0.002809) 5 (0.014045) 15 15 528
----+---------+--------+----------+--------+------+--------+--------
6: 356 356 1.483146 528
For N items over N slots, the expectation for the number of empty slots and the number of slots with a single item in them is equal. The expected density is 1/e for both.
The final number (1.483146) is the number of ->next pointer traversels per found element (when using a chained hash table) Any optimal hash function will almost reach 1.5.

How to extract a pattern from string containing binary data

I have this array that comes from a previous a=array.unpack("C*") command.
a = [9, 32, 50, 53, 56, 53, 57, 9, 73, 78, 70, 79, 9, 73, 78, 70, 79, 53, 9,
32, 55, 52, 32, 50, 51, 32, 48, 51, 32, 57, 50, 32, 48, 48, 32, 48, 48, 32,
48, 48, 32, 69, 67, 32, 48, 50, 32, 49, 48, 32, 48, 48, 32, 69, 50, 32, 48,
48, 32, 55, 55, 9, 0, 0, 0, 0, 1, 12, 1, 0, 0, 0, 57, 254, 70, 6, 1, 6, 0, 3,
0, 3, 198, 0, 2, 198, 31, 147, 23, 0, 226, 7, 12, 17, 18, 56, 55, 3, 101, 1,
1, 0, 134, 7, 145, 5, 148, 37, 150, 133, 241, 135, 5, 22, 109, 145, 53, 38,
171, 4, 3, 2, 6, 192, 173, 22, 160, 20, 48, 18, 6, 9, 42, 134, 58, 0, 137, 97,
58, 1, 0, 164, 5, 48, 3, 129, 1, 7, 225, 16, 2, 1, 1, 4, 11, 9, 1, 10, 10, 6,
2, 19, 105, 145, 103, 116, 226, 35, 48, 3, 194, 1, 242, 48, 3, 194, 1, 241, 48,
3, 194, 1, 246, 48, 3, 194, 1, 245, 48, 3, 194, 1, 244, 48, 3, 194, 1, 243, 48,
3, 194, 1, 247, 177, 13, 10, 1, 1, 4, 8, 10, 6, 2, 19, 105, 145, 103, 116, 0, 0,
42, 3, 0, 0, 48, 48, 48, 48, 48, 48, 48, 50, 9, 82, 101, 99, 101, 105, 118, 101,
9, 50, 51, 9, 77, 111, 110, 32, 32]
when I convert to chr it looks like this:
irb(main):4392:0> a.map(&:chr).join
=> "\t 25859\tINFO\tINFO5\t 74 23 03 92 00 00 00 EC 02 10 00 E2 00 77\t\x00\x00\x00\x00
\x01\f\x01\x00\x00\x009\xFEF\x06\x01\x06\x00\x03\x00\x03\xC6\x00\x02\xC6\x1F\x93\x17\x00
\xE2\a\f\x11\x1287\x03e\x01\x01\x00\x86\a\x91\x05\x94%\x96\x85\xF1\x87\x05\x16m\x915&\xAB
\x04\x03\x02\x06\xC0\xAD\x16\xA0\x140\x12\x06\t*\x86:\x00\x89a:\x01\x00\xA4\x050\x03\x81
\x01\a\xE1\x10\x02\x01\x01\x04\v\t\x01\n\n\x06\x02\x13i\x91gt\xE2#0\x03\xC2\x01\xF20\x03
\xC2\x01\xF10\x03\xC2\x01\xF60\x03\xC2\x01\xF50\x03\xC2\x01\xF40\x03\xC2\x01\xF30\x03\xC2
\x01\xF7\xB1\r\n\x01\x01\x04\b\n\x06\x02\x13i\x91gt\x00\x00*\x03\x00\x000000..."
I would like to extract the hexadecimal values between INFO5\t and \t..., so the output would be
"74 23 03 92 00 00 00 EC 02 10 00 E2 00 77"
I'm doing like below but only removes the first unwanted part and leaves \n\n\x06...000
How can I fix this?
irb(main)>: a.map(&:chr).join.gsub(/(\t .*\t )|(\t.*)/,"")
=> "74 23 03 92 00 00 00 EC 02 10 00 E2 00 77\n\n\x06\x02\x13i\x91gt\xE2#0
\x03\xC2\x01\xF20\x03\xC2\x01\xF10\x03\xC2\x01\xF60\x03\xC2\x01\xF50\x03\xC2
\x01\xF40\x03\xC2\x01\xF30\x03\xC2\x01\xF7\xB1\r\n\x01\x01\x04\b\n\x06\x02\
x13i\x91gt\x00\x00*\x03\x00\x0000000002"
Thanks for the help in advance.
UDPATE
Below attached sample binary file.
input.dat
Here are two approaches (a below is abbreviated from that given in the question).
a = [9, 32, 50, 53, 56, 53, 57, 9, 73, 78, 70, 79, 9, 73, 78, 70, 79, 53, 9,
32, 55, 52, 32, 50, 51, 32, 48, 51, 32, 57, 50, 32, 48, 48, 32, 48, 48,
32, 48, 48, 32, 69, 67, 32, 48, 50, 32, 49, 48, 32, 48, 48, 32, 69, 50,
32, 48, 48, 32, 55, 55, 9, 0, 0]
Extract from the string that had been unpacked to create a
str = a.pack("C*")
#=> "\t 25859\tINFO\tINFO5\t 74 23 03 92 00 00 00 EC 02 10 00 E2 00 77\t\x00\x00"
str[/(?<=INFO5\t).+?(?=\t)/].strip
#=> "74 23 03 92 00 00 00 EC 02 10 00 E2 00 77"
str is the string that had been converted to a (a = str.unpack("C*)), so it need not be computed.
(?<=INFO5\t ) and (?=\t) are respectively a positive lookbehind and a positive lookahead. They must be matched but are not part of the match that is returned. The ("non-greedy") question mark in .+? ensures that the match terminates immediately before the first tab is encountered. By contrast,
"abc\td\tef"[/(?<=a).+(?=\t)/]
#=> "bc\td"
Extract from a and convert to a string
pfix = "INFO5\t".unpack("C*")
#=> [73, 78, 70, 79, 53, 9]
pfix_size = pfix.size
#=> 6
sfix = [prefix.last]
#=> [9]
sfix_size = sfix.size
start = idx_start(a, pfix) + pfix_size
#=> 19
a[start..idx_start(a[start..-1], sfix) + start - 1].pack("C*").strip
#=> "74 23 03 92 00 00 00 EC 02 10 00 E2 00 77"
def idx_start(a, arr)
arr_size = arr.size
a.each_index.find { |i| a[i, arr_size] == arr }
end
I assume you mean a=str.unpack("C*") - you can unpack a string but not an array.
To get the result you want, you don't need to use unpack at all1 - just perform a regex:
str.match(/INFO5\t(.*?)\t/).to_a[1]
# => " 74 23 03 92 00 00 00 EC 02 10 00 E2 00 77"
Note that there's a leading space in the result, but you can adjust the regex according to your needs; I'm not going to try to guess the specification of this format.
Tips:
The ? in .*? is needed to make the * non-greedy.
The to_a avoids raiseing an error in case the match finds nothing.
EDIT
Your comment regarding "invalid byte sequence in UTF-8" indicates that your data is probably ASCII-8BIT (i.e. it's not compatible with UTF-8), but it's stored in a string whose encoding attribute is "UTF-8". It would help if you explain how you obtained that string, because the string's encoding appears to be wrong.
Solution 1 (this is ideal):
Read in the file as ASCII-8BIT:
str = File.read("input.dat", encoding: 'ASCII-8BIT')
Solution 2 (a workaround, if you can't control the input encoding):
# NOTE: this changes the encoding on `str`
str.force_encoding("ASCII-8BIT")
After you've done this, the .match should work.
Further Explanation
The reason your map(&:chr).join works is because .chr will produce either US-ASCII or ASCII-8BIT strings (the latter happens for bytes above 127), never UTF-8.
When you join those strings, your result is in ASCII-8BIT if any byte was above 127. So this is effectively the same as calling force_encoding("ASCII-8BIT"), except that map/join doesn't modify the original string's encoding like force_encoding does.
1unpack is unnecessary because a.map(&:chr).join is the same as arr.pack('C*') which gives you the original str. Even if you had to unpack the string for another purpose, I recommend using the original string instead of re-packing the array. Maybe you can encapsulate this into a data structure, e.g.:
i_data = InfoData.new(str)
i_data.bytes # array of bytes
i_data.hex_string # "74 23 03 ..."
Note that the above code won't work as-is - you need to write the InfoData class yourself.
I assume that you don't need the non-ascii bytes, so in first step I trim them to the first null byte using take_while
Then I convert ints to string using map(&:chr).join
Finally I match them using a regex that /INFO5\t ?([^\t]*)\t/ that assumes the interesting part is between INFO5\t and next \t
--
a=array.unpack("C*")
a.take_while{|e| e > 0}.map(&:chr).join.match(/INFO5\t ?([^\t]*)\t/)[1]
# => "74 23 03 92 00 00 00 EC 02 10 00 E2 00 77"

Check if number is in multiple strings and label

Here is the output I am working with:
Pool Name: Pool 2
Pool ID: 1
LUNs: 1015, 1080, 1034, 1016, 500, 1002, 1062, 1041, 1046, 1028, 1009, 1054, 513, 1058, 1070, 515, 1049, 1083, 1020, 1076, 19, 509, 1057, 1021, 525, 1019, 518, 1075, 29, 23, 1068, 37, 1064, 506, 1024, 1026, 1008, 1087, 1012, 1006, 1018, 502, 1004, 1074, 1030, 1032, 39, 1014, 1005, 1056, 1044, 2, 1033, 1001, 16, 1061, 1040, 1045, 1027, 26, 1023, 1053, 1037, 1079, 512, 520, 1069, 1039, 514, 1048, 1082, 523, 508, 524, 517, 522, 1066, 1089, 1067, 529, 528, 1063, 505, 1081, 527, 1007, 1086, 1051, 1011, 1035, 1017, 501, 1003, 1042, 1073, 1085, 1029, 1010, 24, 1013, 1055, 1043, 1059, 52, 1071, 516, 1050, 1084, 1000, 1077, 1060, 1072, 510, 1022, 1052, 526, 1036, 1078, 511, 35, 519, 1038, 521, 1047, 507, 6, 1065, 1025, 1088, 503, 53, 1031, 504
Pool Name: Pool 1
Pool ID: 0
LUNs: 9, 3, 34, 10, 12, 8, 7, 0, 38, 27, 18, 4, 42, 21, 17, 28, 36, 22, 13, 5, 11, 25, 15, 32, 1
Pool Name: Pool 4
Pool ID: 2
LUNs: (this one is empty)
What I would like to do is store each one of the "LUNs:" into their own variables (array?). Then take my number and search for it in all arrays, in this example there are three. If it matches my number for example "34" the program will output Your number is in Pool 1
I know how to pull the LUN lines I need with Regex expressions and I know how to compare the results with an if statement but get lost combining the two and even more lost when thinking about outputting the correct "Pool Name".
EDIT
I should add the total number of pools can change as well as the LUN number lists.
Convert the output into a single string, replace colons with equals signs and split the string at double line breaks, then convert the fragments into objects using ConvertFrom-StringData and New-Object and split the LUN string into an array:
$data = ... | Out-String
$pools = $data -replace ': +','=' -split "`r`n`r`n" |
% { New-Object -Type PSCustomObject -Property (ConvertFrom-StringData $_) } |
select -Property *,#{n='LUNs';e={$_.LUNs -split ', '}} -Exclude LUNs
With that you can get the pool name of a pool containing a given LUN like this:
$pools | ? { $_.LUNs -contains 34 } | select -Expand 'Pool Name'
I'm sure there's an easier way...
Is that what you need?
$Number = 42
$Lun1=1015, 1080, 1034, 1016, 500, 1002, 1062, 1041, 1046, 1028, 1009, 1054, 513, 1058, 1070
$Lun2=9, 3, 34, 10, 12, 8, 7, 0, 38, 27, 18, 4, 42, 21, 17, 28, 36, 22, 13, 5, 11, 25, 15, 32
$Lun3=$null
$Lun1Length=$Lun1.Length
$Lun2Length=$Lun2.Length
$Lun3Length=$Lun3.Length
[Array]$Luns = $Lun1, $Lun2, $Lun3
foreach ($Lun in $Luns)
{
if ($Lun -contains $Number)
{
Switch ($Lun.Length)
{
$Lun1Length {"$Number in Lun1"}
$Lun2Length {"$Number in Lun2"}
$Lun3Length {"$Number in Lun3"}
}
}
}
42 in Lun2

(C++11) What's the difference between static array and dynamic array with list initialized?

For instance, there is an int array with thousands of elements:
static int st_indices[9999] = {
0, 27, 26, 1, 41, 71, 0, 26, 101, 0, 101, 131, 0, 131, 72,
1, 71, 176, 2, 56, 206, 3, 116, 236, 4, 146, 266, 5, 161, 296,
......
};
and
int* dy_indices = new int[9999] {
0, 27, 26, 1, 41, 71, 0, 26, 101, 0, 101, 131, 0, 131, 72,
1, 71, 176, 2, 56, 206, 3, 116, 236, 4, 146, 266, 5, 161, 296,
......
};
What's the difference between above two ways, especially the values in curly braces on memory usage?
I know that st_indices will life in memory until the program ends(STACK), and dy_indices will be release after delete [](HEAP). or it's a question about stack vs. .DATA segment?
Static are done at compile time..(set amount of memory, aka STACK)
Dynamic are done at run time (dynamic allocation, can be any size depending on system limits, aka HEAP)
From #Dr.Kameleon's answer , I learned that OS will reading the contents of executable file, and loading it into memory.
That is the data in curly braces will be loaded into the .TEXT segment of memory. If we don't take virtual memory/paging into account, putting the data in a file then read in, will reduce the memory usage(for an OpenGL app).

Resources