【Rust】プロセススケジュラー

#[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