#[derive(Debug, Clone, Copy, PartialEq, Eq)] enum ProcessState { Ready, Running, Waiting, Terminated, } #[derive(Debug)] struct Process { pid: usize, state: ProcessState, } struct Scheduler { processes: Vec<Process>, current_index: usize, } impl Scheduler { fn new(processes: Vec<Process>) -> Self { Scheduler { processes, current_index: 0, } } fn schedule(&mut self) -> Option<&Process> { if self.processes.is_empty() { return None; } let len = self.processes.len(); for _ in 0..len { self.current_index = (self.current_index + 1) % len; let proc = &mut self.processes[self.current_index]; if proc.state == ProcessState::Ready { proc.state = ProcessState::Running; return Some(proc); } } None } fn update_state(&mut self, pid: usize, new_state: ProcessState) { if let Some(proc) = self.processes.iter_mut().find(|p| p.pid == pid) { proc.state = new_state; } } } fn main(){ let mut scheduler = Scheduler::new(vec![ Process { pid: 1, state: ProcessState::Ready}, Process { pid: 2, state: ProcessState::Ready}, Process { pid: 3, state: ProcessState::Waiting}, ]); for _ in 0..5 { if let Some(proc) = scheduler.schedule() { println!("Running process: {:?}", proc.pid); scheduler.update_state(proc.pid, ProcessState::Ready); } else { println!("No Runnable processes."); break; } } }
【Rust】メモリ管理
const FRAME_SIZE: usize = 4096; const TOTAL_MEMORY: usize = 1024 * 1024 * 128; const TOTAL_FRAMES: usize = TOTAL_MEMORY / FRAME_SIZE; static mut FRAME_BITMAP: [bool; TOTAL_FRAMES] = [false; TOTAL_FRAMES]; pub struct FrameAllocator; impl FrameAllocator { pub fn alloc() -> Option<usize> { unsafe { for (i, used) in FRAME_BITMAP.iter_mut() enumerate() { if !*used { *used = true; return Some(i * FRAME_SIZE); } } None } } pub fn dealloc(addr: usize) { let index = addr / FRAME_SIZE; if index < TOTAL_FRAMES { unsafe { FRAME_BITMAP[index] = false; } } } }
【Rust】バイナリデータへの処理
### 文字列の変換
fn main() { let text = "Hello, Rust!"; let binary = text.as_bytes(); println!("binary: {:?}", binary); }
binary: [72, 101, 108, 108, 111, 44, 32, 82, 117, 115, 116, 33]
### テキストファイルの変換
input.txt
Hello Rust! This is sample
use std::fs::File; use std::io::{self, Read, Write}; fn main() -> io::Result<()>{ let mut input_file = File::open("./data/input.txt")?; let mut buffer = Vec::new(); input_file.read_to_end(&mut buffer)?; println!("binary: {:?}", &buffer); Ok(()) }
### データのchunk
fn main(){ let data = vec![0u8; 10000]; let chunk_size = 1024; for(i, chunk) in data.chunks(chunk_size).enumerate() { println!("チャンク {}: サイズ = {}", i, chunk.len()); } }
チャンク 0: サイズ = 1024
チャンク 1: サイズ = 1024
チャンク 2: サイズ = 1024
チャンク 3: サイズ = 1024
チャンク 4: サイズ = 1024
チャンク 5: サイズ = 1024
チャンク 6: サイズ = 1024
チャンク 7: サイズ = 1024
チャンク 8: サイズ = 1024
チャンク 9: サイズ = 784
### 画像データのchunk
use std::fs::File; use std::io::{self, Read, Write}; fn main()-> io::Result<()>{ let mut input_file = File::open("./data/test.jpg")?; let mut buffer = Vec::new(); input_file.read_to_end(&mut buffer)?; let chunk_size = 1024; for(i, chunk) in buffer.chunks(chunk_size).enumerate() { println!("チャンク {}: 値 = {:?}", i, chunk); } Ok(()) }
Rustでmalloc, free
use std::alloc::{alloc, dealloc, Layout}; use std::ptr; fn main() { unsafe { let layout = Layout::new::<i32>(); let ptr = alloc(layout) as *mut i32; if ptr.is_null() { panic!("メモリ確保に失敗しました"); } *ptr = 42; println!("ptrが指す値: {}", *ptr); dealloc(ptr as *mut u8, layout); } }
Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.83s
Running `target/debug/memory`
ptrが指す値: 42
【Blockchain】storjをpythonで実装する
import os from cryptography.fernet import Fernet from reedsolo import RSCodec CHUNK_SIZE = 32 DATA_SEGMENTS = 4 TOTAL_SEGMENTS = 8 rsc = RSCodec(TOTAL_SEGMENTS - DATA_SEGMENTS) key = Fernet.generate_key() cipher = Fernet(key) original_data = b"StorjTestData1234567890!ThisIsAChunkTestFile!!" print(f"元データ: {original_data}") encrypted_data = cipher.encrypt(original_data) print(f"暗号化データ: {encrypted_data}") chunks = [encrypted_data[i:i+CHUNK_SIZE] for i in range(0, len(encrypted_data), CHUNK_SIZE)] def encode_chunk(chunk): encoded = rsc.encode(chunk) seg_size = len(encoded) // TOTAL_SEGMENTS return [encoded[i:i+seg_size] for i in range(0, len(encoded), seg_size)] distributed_chunks = [] for chunk in chunks: segments = encode_chunk(chunk) distributed_chunks.append(segments) for i, chunk_segs in enumerate(distributed_chunks): print(f"\n チャンク{i+1}:") for j, seg in enumerate(chunk_segs): print(f" ノード{j}: {seg}") def recover_chunk(pieces): combined = b''.join(pieces) return rsc.decode(combined) recovered_encrypted = b'' for chunk_segs in distributed_chunks: selected_pieces = chunk_segs[:DATA_SEGMENTS] recovered = recover_chunk(selected_pieces) recovered_encrypted += recovered decrypted_data = cipher.decrypt(recoved_encrypted) print(f"\n復元された平文: {decrypted_data}")
$ python3 storj.py
元データ: b’StorjTestData1234567890!ThisIsAChunkTestFile!!’
暗号化データ: b’gAAAAABoLw7a8YpRJbYfA1bt6JOd9Rn28BVtmziV9-qXo9pWs41Or5LN8J0J3UKgAB7uTmpXjkHgTiEv_Dn4ajnfJATxU4lkoOS8xI67SmVeORdvPm6O6OEqGYBXfhQAGaBEtun2jHOw’
チャンク1:
ノード0: bytearray(b’gAAA’)
ノード1: bytearray(b’AABo’)
ノード2: bytearray(b’Lw7a’)
ノード3: bytearray(b’8YpR’)
ノード4: bytearray(b’JbYf’)
ノード5: bytearray(b’A1bt’)
ノード6: bytearray(b’6JOd’)
ノード7: bytearray(b’9Rn2′)
ノード8: bytearray(b”3\’\xf8\xd8″)
チャンク2:
ノード0: bytearray(b’8BVt’)
ノード1: bytearray(b’mziV’)
ノード2: bytearray(b’9-qX’)
ノード3: bytearray(b’o9pW’)
ノード4: bytearray(b’s41O’)
ノード5: bytearray(b’r5LN’)
ノード6: bytearray(b’8J0J’)
ノード7: bytearray(b’3UKg’)
ノード8: bytearray(b’\x1b\xe3=\xc7′)
チャンク3:
ノード0: bytearray(b’AB7u’)
ノード1: bytearray(b’TmpX’)
ノード2: bytearray(b’jkHg’)
ノード3: bytearray(b’TiEv’)
ノード4: bytearray(b’_Dn4′)
ノード5: bytearray(b’ajnf’)
ノード6: bytearray(b’JATx’)
ノード7: bytearray(b’U4lk’)
ノード8: bytearray(b’t\x915\xa3′)
チャンク4:
ノード0: bytearray(b’oOS8′)
ノード1: bytearray(b’xI67′)
ノード2: bytearray(b’SmVe’)
ノード3: bytearray(b’ORdv’)
ノード4: bytearray(b’Pm6O’)
ノード5: bytearray(b’6OEq’)
ノード6: bytearray(b’GYBX’)
ノード7: bytearray(b’fhQA’)
ノード8: bytearray(b’e\x02al’)
チャンク5:
ノード0: bytearray(b’Ga’)
ノード1: bytearray(b’BE’)
ノード2: bytearray(b’tu’)
ノード3: bytearray(b’n2′)
ノード4: bytearray(b’jH’)
ノード5: bytearray(b’Ow’)
ノード6: bytearray(b’\x00\xea’)
ノード7: bytearray(b’\x8b\x07′)
【Blockchain】siaをpythonで実装する
データをchunkして、encodeして、セグメントに分割して、nodeに保存する
import math from reedsolo import RSCodec import random SEGMENT_SIZE = 8 DATA_SEGMENTS = 4 TOTAL_SEGMENTS = 6 CHUNK_SIZE = SEGMENT_SIZE * DATA_SEGMENTS rsc = RSCodec(TOTAL_SEGMENTS - DATA_SEGMENTS) def generate_fake_file(size=40): return bytearray([random.randint(0, 255) for _ in range(size)]) def split_into_chunks(data, chunk_size): return [data[i:i+chunk_size] for i in range(0, len(data), chunk_size)] def encode_chunk(chunk): segments = [chunk[i:i+SEGMENT_SIZE] for i in range(0, len(chunk), SEGMENT_SIZE)] joined_data = b''.join(segments) encoded = rsc.encode(joined_data) seg_len = len(encoded) // TOTAL_SEGMENTS encoded_segments = [encoded[i:i+seg_len] for i in range(0, len(encoded), seg_len)] return encoded_segments def distribute_segments(segments): nodes = {} for i, seg in enumerate(segments): nodes[f"node_{i}"] = seg return nodes fake_file = generate_fake_file(40) print(fake_file) chunks = split_into_chunks(fake_file, CHUNK_SIZE) for i, chunk in enumerate(chunks): print(f"チャンク {i+1}: {chunk}") encoded_segments = encode_chunk(chunk) print(f" ↳ 符号化セグメント数: {len(encoded_segments)} ") distributed = distribute_segments(encoded_segments) for node, seg in distributed.items(): print(f" {node}に保存: {seg}") print()
$ python3 sia.py
bytearray(b”Xz\xe12\x1a\xe7aq\xf3\’\x11\xcb\xa7\xf0\x0f*r\xd5Y4y#|\xb2\xe0\xeb\xb4\x14+\xedl\xe2\xf9\x1b\xe9s\x93\xc0\x94\xde”)
チャンク 1: bytearray(b”Xz\xe12\x1a\xe7aq\xf3\’\x11\xcb\xa7\xf0\x0f*r\xd5Y4y#|\xb2\xe0\xeb\xb4\x14+\xedl\xe2″)
↳ 符号化セグメント数: 7
node_0に保存: bytearray(b’Xz\xe12\x1a’)
node_1に保存: bytearray(b”\xe7aq\xf3\'”)
node_2に保存: bytearray(b’\x11\xcb\xa7\xf0\x0f’)
node_3に保存: bytearray(b’*r\xd5Y4′)
node_4に保存: bytearray(b’y#|\xb2\xe0′)
node_5に保存: bytearray(b’\xeb\xb4\x14+\xed’)
node_6に保存: bytearray(b’l\xe2q\xac’)
チャンク 2: bytearray(b’\xf9\x1b\xe9s\x93\xc0\x94\xde’)
↳ 符号化セグメント数: 10
node_0に保存: bytearray(b’\xf9′)
node_1に保存: bytearray(b’\x1b’)
node_2に保存: bytearray(b’\xe9′)
node_3に保存: bytearray(b’s’)
node_4に保存: bytearray(b’\x93′)
node_5に保存: bytearray(b’\xc0′)
node_6に保存: bytearray(b’\x94′)
node_7に保存: bytearray(b’\xde’)
node_8に保存: bytearray(b’\xb9′)
node_9に保存: bytearray(b’\xd8′)
C++のメモリの扱い
C言語はメモリ確保関数だったが、C++は命令で確保する
### メモリ確保/解放命令
– new
メモリを確保する命令
確保できない場合はstd::bad_allocを投げる
std::nothrowを指定すると、例外ではなくnullptrを返す
– delete
newで確保した領域を解放する命令
– delete[]
newで確保した領域を解放する命令
# include <memory> int main() { // 通常の確保 char* p = new char[100]; char* p2 = nullptr; try { p2 = new char[100]; } catch (const std::bad_alloc& e) { } char* p3 = new(std::nothrow) char[100]; if (p3 == nullptr) { } // 指定した領域からメモリを確保する char buf[100]; char* p4 = new (buf) char[100]; int* n = new int; int* n2 = new int(); int* n3 = new int(10); delete n3; delete n2; delete n; delete[] p3; delete[] p2; delete[] p; }
#include <iostream> int main() { int* p = new int; *p = 77; std::cout << *p << std::endl; delete p; }
### 配列の確保
#include <iostream> int main() { int* arr = new int[5]; for (int i = 0; i < 5; ++i) arr[i] = i * 10; for (int i = 0; i < 5; ++i) std::cout << arr[i] << " "; delete[] arr; return 0; }
$ ./test
0 10 20 30 40
### スマートポインタ
#include <iostream> #include <memory> class Sample { public: void greet() { std::cout << "Hello from Sample!\n"; } }; int main() { std::unique_ptr<Sample> ptr = std::make_unique<Sample>(); ptr->greet(); return 0; }
C言語のメモリの扱い
### メモリ管理の概要
1. メモリ確保
2. メモリ解放
の順番で制御する
– メモリリーク
確保したメモリを不要になっても解放せずにいると、結果としてメモリ不足となって確保できなくなる
### メモリ確保・解放関数
– malloc
指定されたサイズのメモリを確保する
確保できない場合はNullを返す
– calloc
指定されたサイズのメモリブロックを確保し、確保した領域を0クリアする
確保できない場合はNullを返す
– realloc
確保済みのメモリを拡張する
確保できない場合はNullを返す
– free
malloc, calloc, reallocで確保した領域を解放する関数
# include <stdlib.h> int main(void) { printf("Practice C Memory Programming!! \n"); // 100 byteのメモリ確保 char* p = malloc(100); if (p == NULL) { // 確保できなかった時の処理 } int* p2 = calloc(100, sizeof(int)); if (p2 == NULL){} char* p3 = realloc(p, 200); if (p3 == NULL) { } else { p = p3; } free(p2); free(p); return 0; }
#include <stdio.h> #include <stdlib.h> int main() { printf("Practice C Memory Programming!! \n"); int *p; p = (int *)malloc(sizeof(int)); if (p == NULL) { printf("メモリの確保に失敗しました\n"); return 1; } *p = 55; printf("pが指す値: %d\n", *p); free(p); return 0; }
$ ./test
Practice C Memory Programming!!
pが指す値: 55
配列の場合
#include <stdio.h> #include <stdlib.h> int main() { printf("Practice C Memory Programming!! \n"); int *arr; int n = 5; arr = (int *)malloc(n * sizeof(int)); if (arr == NULL) { printf("メモリの確保に失敗しました\n"); return 1; } for (int i = 0; i < n; i++){ arr[i] = i * 10; } for (int i = 0; i < n; i++) { printf("arr[%d] = %d\n", i, arr[i]); } free(arr); return 0; }
$ ./test
Practice C Memory Programming!!
arr[0] = 0
arr[1] = 10
arr[2] = 20
arr[3] = 30
arr[4] = 40
ipfsの利用
### ローカル環境でのipfs
$ echo “version 1 of my text” > mytextfile.txt
$ cat mytextfile.txt
version 1 of my text
$ ipfs cat QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy
version 1 of my text
これをipfsネットワークで実行したい
### ipfsに接続
# ipfs daemon
別のターミナルで以下を実行
# ipfs swarm peers |head
/ip4/103.253.72.2/tcp/4001/p2p/12D3KooWMGNgfvPVhUdzWfGifHMkVvJ991EQCCEWXTREc8CPHui7
/ip4/104.244.76.218/tcp/4001/p2p/12D3KooWMbUuHSEvy4KNnkW8H9m63zesuuvVNS25hTL1SQtRh835
/ip4/109.123.240.146/tcp/4001/p2p/12D3KooWPzJcDSFQrBSgrdPbSAwTX5x6aWKWAoAzuEj3NBb43iKD
/ip4/109.203.194.197/tcp/56881/p2p/12D3KooWMgRnDE2oPkd72ZVb3pw4Pww9F24nVfCPj18gB1ARhUCt
/ip4/112.25.240.107/tcp/4001/p2p/12D3KooWHkTtvW6qCR9yATp6g8EC6hHRZGEiybyLQqmsRwoJ7Ac2
/ip4/113.89.245.184/tcp/15088/p2p/12D3KooWD8U6239pcaHdYqrg175DwM9EvFxLMuWo5PjzHd7bLZ15
/ip4/115.204.117.91/tcp/35129/p2p/12D3KooWGknnwvTJwjzYHpXgYU5K6fF2P9d8wtT3zBYudwnA7XmZ
/ip4/117.26.88.117/tcp/51698/p2p/QmQGeMkzJmkWum4FQwxvx6QPTvuNTsGoXBXeCxsWMrHg31
/ip4/136.243.46.54/tcp/4001/p2p/12D3KooWMahkHusnsTbMGVnCyXmKyLyifD8VnpMiH4hKNn6wqPfb
/ip4/136.244.116.199/tcp/4001/p2p/12D3KooWCXC9dBZZsA6E2jJh8SoyGCsGbFSLQtBquthoQpqjgpKp
ubuntuにipfsのインストール
$ wget https://dist.ipfs.io/go-ipfs/v0.5.0/go-ipfs_v0.5.0_linux-arm64.tar.gz
$ tar xvzf go-ipfs_v0.5.0_linux-arm64.tar.gz
$ cd go-ipfs/
$ sudo ./install.sh
Moved ./ipfs to /usr/local/bin
$ ipfs version
ipfs version 0.5.0
$ ipfs init
initializing IPFS node at /home/vagrant/.ipfs
generating 2048-bit RSA keypair…done
peer identity: QmWKa24RSJMHNZNSWiB5FuUkLQFvkM7L8ZqhmUKaUbLAJF
to get started, enter:
ipfs cat /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme
$ ipfs cat /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme
Hello and Welcome to IPFS!
██╗██████╗ ███████╗███████╗
██║██╔══██╗██╔════╝██╔════╝
██║██████╔╝█████╗ ███████╗
██║██╔═══╝ ██╔══╝ ╚════██║
██║██║ ██║ ███████║
╚═╝╚═╝ ╚═╝ ╚══════╝
If you’re seeing this, you have successfully installed
IPFS and are now interfacing with the ipfs merkledag!
——————————————————-
| Warning: |
| This is alpha software. Use at your own discretion! |
| Much is missing or lacking polish. There are bugs. |
| Not yet secure. Read the security notes for more. |
——————————————————-
Check out some of the other files in this directory:
./about
./help
./quick-start <-- usage examples
./readme <-- this file
./security-notes
$ ls ~/.ipfs
blocks config datastore datastore_spec keystore version