tf_idf_vectorizer/utils/datastruct/vector/
mod.rs

1// pub mod math;
2pub mod serde;
3
4use std::{alloc::{alloc, dealloc, realloc, Layout}, fmt, marker::PhantomData, mem, ptr::{self, NonNull}};
5use std::ops::Index;
6use std::fmt::Debug;
7
8use num_traits::Num;
9/// ZeroSpVecは0要素を疎とした過疎ベクトルを実装です
10/// indices と valuesを持ち
11/// indicesは要素のインデックスを保持し、
12/// valuesは要素の値を保持します
13/// 
14/// 要素はindicesの昇順でソートされていることを保証します
15pub struct ZeroSpVec<N>  
16where N: Num
17{
18    buf: RawZeroSpVec<N>,
19    len: usize,
20    nnz: usize,
21    zero: N,
22}
23
24pub trait ZeroSpVecTrait<N>: Clone + Default + Index<usize, Output = N>
25where N: Num
26{
27    unsafe fn ind_ptr(&self) -> *mut u32;
28    unsafe fn val_ptr(&self) -> *mut N;
29    unsafe fn raw_push(&mut self, index: usize, value: N);
30    fn ind_binary_search(&self, index: usize, cut_down: usize) -> Result<usize, usize>;
31    fn new() -> Self;
32    fn with_capacity(cap: usize) -> Self;
33    fn reserve(&mut self, additional: usize);
34    fn shrink_to_fit(&mut self);
35    fn is_empty(&self) -> bool;
36    fn len(&self) -> usize;
37    unsafe fn set_len(&mut self, len: usize);
38    fn capacity(&self) -> usize;
39    fn nnz(&self) -> usize;
40    fn add_dim(&mut self, dim: usize);
41    fn clear(&mut self);
42    fn push(&mut self, elem: N);
43    fn pop(&mut self) -> Option<N>;
44    fn get(&self, index: usize) -> Option<&N>;
45    fn raw_get(&self, index: usize) -> Option<ValueWithIndex<'_, N>>;
46    fn get_with_cut_down(&self, index: usize, cut_down: usize) -> Option<&N>;
47    fn raw_get_with_cut_down(&self, index: usize, cut_down: usize) -> Option<ValueWithIndex<'_, N>>;
48    fn get_ind(&self, index: usize) -> Option<usize>;
49    fn remove(&mut self, index: usize) -> N;
50    fn from_vec(vec: Vec<N>) -> Self;
51    unsafe fn from_raw_iter(iter: impl Iterator<Item = (usize, N)>, len: usize) -> Self;
52    unsafe fn from_sparse_iter(iter: impl Iterator<Item = (usize, N)>, len: usize) -> Self;
53    fn iter(&self) -> ZeroSpVecIter<'_, N>;
54    fn raw_iter(&self) -> ZeroSpVecRawIter<'_, N>;
55}
56
57pub struct ValueWithIndex<'a, N>
58where N: Num
59{
60    pub index: usize,
61    pub value: &'a N,
62}
63
64impl<N> ZeroSpVecTrait<N> for ZeroSpVec<N> 
65where N: Num
66{
67    #[inline]
68    unsafe fn ind_ptr(&self) -> *mut u32 {
69        self.buf.ind_ptr.as_ptr()
70    }
71
72    #[inline]
73    unsafe fn val_ptr(&self) -> *mut N {
74        self.buf.val_ptr.as_ptr()
75    }
76
77    /// raw_pushは、要素を追加するためのメソッド
78    /// ただしlenを更新しない
79    /// 
80    /// # Arguments
81    /// - `index` - 追加する要素のインデックス
82    /// - `value` - 追加する要素の値
83    #[inline]
84    unsafe fn raw_push(&mut self, index: usize, value: N) {
85        if self.nnz == self.buf.cap {
86            self.buf.grow();
87        }
88        unsafe {
89            let val_ptr = self.val_ptr().add(self.nnz);
90            let ind_ptr = self.ind_ptr().add(self.nnz);
91            ptr::write(val_ptr, value);
92            debug_assert!(index <= u32::MAX as usize, "index overflow for u32 storage");
93            ptr::write(ind_ptr, index as u32);
94        }
95        self.nnz += 1;
96    }
97
98    #[inline]
99    fn ind_binary_search(&self, index: usize, cut_down: usize) -> Result<usize, usize> {
100        // 要素が無い場合 Err(0)
101        if self.nnz == 0 {
102            return Err(0);
103        }
104        let mut left = cut_down;
105        let mut right = self.nnz - 1;
106        while left < right {
107            let mid = left + (right - left) / 2;
108            // read は mid < nnz を満たすため安全...
109            let mid_index = unsafe { *self.ind_ptr().add(mid) as usize };
110            if mid_index == index {
111                return Ok(mid);
112            } else if mid_index < index {
113                left = mid + 1;
114            } else {
115                right = mid;
116            }
117        }
118
119        let final_index = unsafe { *self.ind_ptr().add(left) as usize };
120        if final_index == index {
121            Ok(left)
122        } else if final_index < index {
123            Err(left + 1)
124        } else {
125            Err(left)
126        }
127    }
128
129    #[inline]
130    fn new() -> Self {
131        ZeroSpVec {
132            buf: RawZeroSpVec::new(),
133            len: 0,
134            nnz: 0,
135            zero: N::zero(),
136        }
137    }
138
139    #[inline]
140    fn with_capacity(cap: usize) -> Self {
141        let mut buf = RawZeroSpVec::new();
142        buf.cap = cap;
143        buf.cap_set();
144        ZeroSpVec {
145            buf: buf,
146            len: 0,
147            nnz: 0,
148            zero: N::zero(),
149        }
150    }
151
152    /// capの拡張
153    #[inline]
154    fn reserve(&mut self, additional: usize) {
155        let new_cap = self.nnz + additional;
156        if new_cap > self.buf.cap {
157            self.buf.cap = new_cap;
158            self.buf.re_cap_set();
159        }
160    }
161
162    /// capの最適化 未使用領域を解放
163    #[inline]
164    fn shrink_to_fit(&mut self) {
165        if self.len < self.buf.cap {
166            let new_cap = self.nnz;
167            self.buf.cap = new_cap;
168            self.buf.re_cap_set();
169        }
170    }
171
172    #[inline]
173    fn is_empty(&self) -> bool {
174        self.len == 0
175    }
176
177    #[inline]
178    fn len(&self) -> usize {
179        self.len
180    }
181
182    #[inline]
183    unsafe fn set_len(&mut self, len: usize) {
184        self.len = len;
185    }
186
187    /// capacityを返す
188    #[inline]
189    fn capacity(&self) -> usize {
190        self.buf.cap
191    }
192
193    /// nnz(Number of Non-Zero)を返す
194    #[inline]
195    fn nnz(&self) -> usize {
196        self.nnz
197    }
198
199    /// ベクトルの次元数を追加します
200    #[inline]
201    fn add_dim(&mut self, dim: usize) {
202        self.len += dim;
203    }
204
205    /// 全要素を削除します
206    /// cap は維持されるのでメモリを解放したけりゃ shrink_to_fit を呼んで
207    #[inline]
208    fn clear(&mut self) {
209        while let Some(_) = self.pop() {
210            // do nothing
211        }
212    }
213
214    #[inline]
215    fn push(&mut self, elem: N) {
216        if self.nnz == self.buf.cap {
217            self.buf.grow();
218        }
219        if elem != N::zero() {
220            unsafe {
221                let val_ptr = self.val_ptr().add(self.nnz);
222                let ind_ptr = self.ind_ptr().add(self.nnz);
223                ptr::write(val_ptr, elem);
224                debug_assert!(self.len <= u32::MAX as usize, "index overflow for u32 storage");
225                ptr::write(ind_ptr, self.len as u32);
226            }
227            self.nnz += 1;
228        }
229        self.len += 1;
230    }
231
232    #[inline]
233    fn pop(&mut self) -> Option<N> {
234        if self.nnz == 0 {
235            return None;
236        }
237        let pop_element = if self.nnz == self.len {
238            self.nnz -= 1;
239            unsafe {
240                Some(ptr::read(self.val_ptr().add(self.nnz)))
241            }
242        } else {
243            Some(N::zero())
244        };
245        self.len -= 1;
246        pop_element
247    }
248
249    #[inline]
250    fn get(&self, index: usize) -> Option<&N> {
251        if index >= self.len {
252            return None;
253        }
254        match self.ind_binary_search(index, 0) {
255            Ok(idx) => {
256                unsafe {
257                    Some(&*self.val_ptr().add(idx))
258                }
259            },
260            Err(_) => {
261                Some(&self.zero)
262            }
263        }
264    }
265
266    #[inline]
267    fn raw_get(&self, index: usize) -> Option<ValueWithIndex<'_, N>> {
268        if index >= self.len {
269            return None;
270        }
271        match self.ind_binary_search(index, 0) {
272            Ok(idx) => {
273                unsafe {
274                    Some(ValueWithIndex {
275                        index,
276                        value: &*self.val_ptr().add(idx),
277                    })
278                }
279            },
280            Err(_) => {
281                Some(ValueWithIndex {
282                    index,
283                    value: &self.zero,
284                })
285            }
286        }
287    }
288
289    #[inline]
290    fn get_with_cut_down(&self, index: usize, cut_down: usize) -> Option<&N> {
291        if index >= self.len {
292            return None;
293        }
294        match self.ind_binary_search(index, cut_down) {
295            Ok(idx) => {
296                unsafe {
297                    Some(&*self.val_ptr().add(idx))
298                }
299            },
300            Err(_) => {
301                Some(&self.zero)
302            }
303        }
304    }
305
306    #[inline]
307    fn raw_get_with_cut_down(&self, index: usize, cut_down: usize) -> Option<ValueWithIndex<'_, N>> {
308        if index >= self.len || cut_down >= self.nnz {
309            return None;
310        }
311        match self.ind_binary_search(index, cut_down) {
312            Ok(idx) => {
313                unsafe {
314                    Some(ValueWithIndex {
315                        index,
316                        value: &*self.val_ptr().add(idx),
317                    })
318                }
319            },
320            Err(_) => {
321                Some(ValueWithIndex {
322                    index,
323                    value: &self.zero,
324                })
325            }
326        }
327    }
328
329    #[inline]
330    fn get_ind(&self, index: usize) -> Option<usize> {
331        if index >= self.nnz {
332            return None;
333        }
334        unsafe {
335            Some(ptr::read(self.ind_ptr().add(index)) as usize)
336        }
337    }
338
339
340
341    /// removeメソッド
342    /// 
343    /// `index` 番目の要素を削除し、削除した要素を返します。
344    /// - 論理インデックス `index` が物理的に存在すれば、その値を返す
345    /// - 物理的になければ(= デフォルト扱いだった)デフォルト値を返す
346    /// 
347    /// # Arguments
348    /// - `index` - 削除する要素の論理インデックス
349    /// 
350    /// # Returns
351    /// - `N` - 削除した要素の値
352    #[inline]
353    fn remove(&mut self, index: usize) -> N {
354        debug_assert!(index < self.len, "index out of bounds");
355        
356        // 論理的な要素数は常に1つ減る
357        self.len -= 1;
358
359        match self.ind_binary_search(index, 0) {
360            Ok(i) => {
361                // 今回削除する要素を読みだす
362                let removed_val = unsafe {
363                    ptr::read(self.val_ptr().add(i))
364                };
365
366                // `i` 番目を削除するので、後ろを前にシフト
367                let count = self.nnz - i - 1;
368                if count > 0 {
369                    unsafe {
370                        // 値をコピーして前につめる
371                        ptr::copy(
372                            self.val_ptr().add(i + 1),
373                            self.val_ptr().add(i),
374                            count
375                        );
376                        // インデックスもコピーして前につめる
377                        ptr::copy(
378                            self.ind_ptr().add(i + 1),
379                            self.ind_ptr().add(i),
380                            count
381                        );
382                        // シフトした後のインデックスは全て -1
383                        for offset in i..(self.nnz - 1) {
384                            *self.ind_ptr().add(offset) -= 1;
385                        }
386                    }
387                }
388                // nnzは 1 減
389                self.nnz -= 1;
390
391                // 取り除いた要素を返す
392                removed_val
393            }
394            Err(i) => {
395                // index は詰める必要があるので、i 以降の要素のインデックスを -1
396                // (たとえば “要素自体は無い” けど、後ろにある要素は
397                //  論理インデックスが 1 つ前になる)
398                if i < self.nnz {
399                    unsafe {
400                        for offset in i..self.nnz {
401                            *self.ind_ptr().add(offset) -= 1;
402                        }
403                    }
404                }
405
406                // 0返す
407                N::zero()
408            }
409        }
410    }
411
412    /// ベクトルをVecから構築します
413    #[inline]
414    fn from_vec(vec: Vec<N>) -> Self {
415        let mut zero_sp_vec = ZeroSpVec::with_capacity(vec.len());
416        for entry in vec {
417            zero_sp_vec.push(entry);
418        }
419        zero_sp_vec
420    }
421
422    /// (idx, value)のイテレータから構築します
423    /// これはfrom_sparse_iterと異なり、0要素も含めて構築します
424    #[inline]
425    unsafe fn from_raw_iter(iter: impl Iterator<Item = (usize, N)>, len: usize) -> Self {
426        let mut zero_sp_vec = ZeroSpVec::with_capacity(iter.size_hint().0);
427        for (index, value) in iter {
428            unsafe {
429                zero_sp_vec.raw_push(index, value);
430            }
431        }
432        zero_sp_vec.len = len;
433        zero_sp_vec
434    }
435
436    /// (idx, value)のイテレータから構築します
437    /// これは0要素を自動でスキップします
438    #[inline]
439    unsafe fn from_sparse_iter(iter: impl Iterator<Item = (usize, N)>, len: usize) -> Self {
440        let mut zero_sp_vec = ZeroSpVec::new();
441        for (index, value) in iter {
442            if value != N::zero() {
443                unsafe {
444                    zero_sp_vec.raw_push(index, value);
445                }
446            }
447        }
448        zero_sp_vec.len = len;
449        zero_sp_vec
450    }
451
452    /// イテレータを返す
453    /// これはVecと同様に0要素も含めて返す
454    #[inline]
455    fn iter(&self) -> ZeroSpVecIter<'_, N> {
456        ZeroSpVecIter {
457            vec: self,
458            pos: 0,
459        }
460    }
461
462    /// 生イテレータを返す
463    /// これは0要素を含めず、実際に格納されている(idx, value)ペアのみを返す
464    #[inline]
465    fn raw_iter(&self) -> ZeroSpVecRawIter<'_, N> {
466        ZeroSpVecRawIter {
467            vec: self,
468            pos: 0,
469        }
470    }
471}
472
473unsafe impl <N: Num + Send> Send for ZeroSpVec<N> {}
474unsafe impl <N: Num + Sync> Sync for ZeroSpVec<N> {}
475
476impl<N> Clone for ZeroSpVec<N> 
477where N: Num
478{
479    #[inline]
480    fn clone(&self) -> Self {
481        ZeroSpVec {
482            buf: self.buf.clone(),
483            len: self.len,
484            nnz: self.nnz,
485            zero: N::zero(),
486        }
487    }
488}
489
490impl<N> Drop for ZeroSpVec<N> 
491where N: Num
492{
493    #[inline]
494    fn drop(&mut self) {
495        // RawZeroSpVecで実装済み
496    }
497}
498
499impl<N> Default for ZeroSpVec<N> 
500where N: Num
501{
502    #[inline]
503    fn default() -> Self {
504        ZeroSpVec::new()
505    }
506}
507
508impl<N> Index<usize> for ZeroSpVec<N> 
509where N: Num
510{
511    type Output = N;
512
513    #[inline]
514    fn index(&self, index: usize) -> &Self::Output {
515        self.get(index).expect("index out of bounds")
516    }
517}
518
519impl<N: Num + Debug> Debug for ZeroSpVec<N> {
520    #[inline]
521    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
522        if f.sign_plus() {
523            f.debug_struct("DefaultSparseVec")
524                .field("buf", &self.buf)
525                .field("nnz", &self.nnz)
526                .field("len", &self.len)
527                .field("zero", &self.zero)
528                .finish()
529        } else if f.alternate() {
530            write!(f, "ZeroSpVec({:?})", self.iter().collect::<Vec<&N>>())
531        } else {
532            f.debug_list().entries((0..self.len).map(|i| self.get(i).unwrap())).finish()
533        }
534    }
535}
536
537#[derive(Clone, Copy)]
538pub struct ZeroSpVecIter<'a, N> 
539where N: Num
540{
541    vec: &'a ZeroSpVec<N>,
542    pos: usize,
543}
544
545impl<'a, N> Iterator for ZeroSpVecIter<'a, N> 
546where N: Num
547{
548    type Item = &'a N;
549
550    #[inline]
551    fn next(&mut self) -> Option<Self::Item> {
552        self.vec.get(self.pos).map(|val| {
553            self.pos += 1;
554            val
555        })
556    }
557}
558
559#[derive(Clone, Copy)]
560pub struct ZeroSpVecRawIter<'a, N> 
561where N: Num
562{
563    vec: &'a ZeroSpVec<N>,
564    pos: usize,
565}
566
567impl<'a, N> Iterator for ZeroSpVecRawIter<'a, N> 
568where N: Num
569{
570    type Item = (usize, &'a N);
571
572    #[inline]
573    fn next(&mut self) -> Option<Self::Item> {
574        if self.pos < self.vec.nnz() {
575            let index = unsafe { *self.vec.ind_ptr().add(self.pos) as usize };
576            let value = unsafe { &*self.vec.val_ptr().add(self.pos) };
577            self.pos += 1;
578            Some((index, value))
579        } else {
580            None
581        }
582    }
583
584    #[inline]
585    fn nth(&mut self, n: usize) -> Option<Self::Item> {
586        let nnz = self.vec.nnz();
587        match self.pos.checked_add(n) {
588            Some(new_pos) if new_pos < nnz => {
589                self.pos = new_pos;
590                self.next()
591            }
592            _ => {
593                self.pos = nnz;
594                None
595            }
596        }
597    }
598
599    #[inline]
600    fn size_hint(&self) -> (usize, Option<usize>) {
601        let remaining = self.vec.nnz().saturating_sub(self.pos);
602        (remaining, Some(remaining))
603    }
604
605}
606
607impl<'a, N> ExactSizeIterator for ZeroSpVecRawIter<'a, N>
608where
609    N: Num,
610{
611    #[inline]
612    fn len(&self) -> usize {
613        self.vec.nnz().saturating_sub(self.pos)
614    }
615}
616
617impl<'a, N> std::iter::FusedIterator for ZeroSpVecRawIter<'a, N>
618where
619    N: Num,
620{
621}
622
623impl<T> From<Vec<T>> for ZeroSpVec<T>
624where T: Num
625{
626    #[inline]
627    fn from(vec: Vec<T>) -> Self {
628        ZeroSpVec::from_vec(vec)
629    }
630}
631
632impl<'a, N> From<ZeroSpVecRawIter<'a, N>> for ZeroSpVec<N>
633where
634    N: Num + Copy,
635{
636    #[inline]
637    fn from(iter: ZeroSpVecRawIter<'a, N>) -> Self {
638        let mut vec = ZeroSpVec::new();
639        for (idx, val) in iter {
640            unsafe {
641                vec.raw_push(idx, *val);
642            }
643            vec.len += 1;
644        }
645        vec
646    }
647}
648
649
650
651
652
653
654
655
656
657/// ZeroSpVecの生実装
658#[derive(Debug)]
659struct RawZeroSpVec<N> 
660where N: Num 
661{
662    val_ptr: NonNull<N>,
663    ind_ptr: NonNull<u32>,
664    /// cap 定義
665    /// 0 => メモリ未確保 (flag)
666    /// usize::MAX =>  zero size struct (ZST) として定義 処理の簡略化を実施 (flag)
667    /// _ => 実際のcapN
668    cap: usize,
669    _marker: PhantomData<N>, // 所有権管理用にPhantomDataを追加
670}
671
672impl<N> RawZeroSpVec<N> 
673where N: Num
674{
675    #[inline]
676    fn new() -> Self {
677        // zero size struct (ZST)をusize::MAXと定義 ある種のフラグとして使用
678        let cap = if mem::size_of::<N>() == 0 { std::usize::MAX } else { 0 }; 
679
680        RawZeroSpVec {
681            // 空のポインタを代入しておく メモリ確保を遅延させる
682            val_ptr: NonNull::dangling(),
683            // 空のポインタを代入しておく メモリ確保を遅延させる
684            ind_ptr: NonNull::dangling(),
685            cap: cap,
686            _marker: PhantomData,
687        }
688    }
689
690    #[inline]
691    fn grow(&mut self) {
692        unsafe {
693            let val_elem_size = mem::size_of::<N>();
694            let ind_elem_size = mem::size_of::<u32>();
695
696            // 安全性: ZSTの場合growはcapを超えた場合にしか呼ばれない
697            // これは必然的にオーバーフローしていることをしめしている
698            debug_assert!(val_elem_size != 0, "capacity overflow");
699
700            // アライメントの取得 適切なメモリ確保を行うため
701            let t_align = mem::align_of::<N>();
702            let usize_align = mem::align_of::<u32>();
703
704            // アロケーション
705            let (new_cap, val_ptr, ind_ptr): (usize, *mut N, *mut u32) = 
706                if self.cap == 0 {
707                    let new_val_layout = Layout::from_size_align(val_elem_size, t_align).expect("Failed to create memory layout");
708                    let new_ind_layout = Layout::from_size_align(ind_elem_size, usize_align).expect("Failed to create memory layout");
709                    (
710                        1,
711                        alloc(new_val_layout) as *mut N,
712                        alloc(new_ind_layout) as *mut u32,
713                    )
714                } else {
715                    // 効率化: cap * 2 でメモリを確保する 見た目上はO(log n)の増加を実現
716                    let new_cap = self.cap * 2;
717                    let new_val_layout = Layout::from_size_align(val_elem_size * self.cap, t_align).expect("Failed to create memory layout for reallocation");
718                    let new_ind_layout = Layout::from_size_align(ind_elem_size * self.cap, usize_align).expect("Failed to create memory layout for reallocation");
719                    (
720                        new_cap,
721                        realloc(self.val_ptr.as_ptr() as *mut u8, new_val_layout, val_elem_size * new_cap) as *mut N,
722                        realloc(self.ind_ptr.as_ptr() as *mut u8, new_ind_layout, ind_elem_size * new_cap) as *mut u32,
723                    )
724                };
725
726            // アロケーション失敗時の処理
727            if val_ptr.is_null() || ind_ptr.is_null() {
728                oom();
729            }
730
731            // selfに返却
732            self.val_ptr = NonNull::new_unchecked(val_ptr);
733            self.ind_ptr = NonNull::new_unchecked(ind_ptr);
734            self.cap = new_cap;
735        }
736    }
737    
738    #[inline]
739    fn cap_set(&mut self) {
740        unsafe {
741            let val_elem_size = mem::size_of::<N>();
742            let ind_elem_size = mem::size_of::<u32>();
743
744            let t_align = mem::align_of::<N>();
745            let usize_align = mem::align_of::<u32>();
746
747            let new_val_layout = Layout::from_size_align(val_elem_size * self.cap, t_align).expect("Failed to create memory layout");
748            let new_ind_layout = Layout::from_size_align(ind_elem_size * self.cap, usize_align).expect("Failed to create memory layout");
749            let new_val_ptr = alloc(new_val_layout) as *mut N;
750            let new_ind_ptr = alloc(new_ind_layout) as *mut u32;
751            if new_val_ptr.is_null() || new_ind_ptr.is_null() {
752                oom();
753            }
754            self.val_ptr = NonNull::new_unchecked(new_val_ptr);
755            self.ind_ptr = NonNull::new_unchecked(new_ind_ptr);
756        }
757    }
758
759    #[inline]
760    fn re_cap_set(&mut self) {
761        unsafe {
762            let val_elem_size = mem::size_of::<N>();
763            let ind_elem_size = mem::size_of::<u32>();
764
765            let t_align = mem::align_of::<N>();
766            let usize_align = mem::align_of::<u32>();
767
768            let new_val_layout = Layout::from_size_align(val_elem_size * self.cap, t_align).expect("Failed to create memory layout");
769            let new_ind_layout = Layout::from_size_align(ind_elem_size * self.cap, usize_align).expect("Failed to create memory layout");
770            let new_val_ptr = realloc(self.val_ptr.as_ptr() as *mut u8, new_val_layout, val_elem_size * self.cap) as *mut N;
771            let new_ind_ptr = realloc(self.ind_ptr.as_ptr() as *mut u8, new_ind_layout, ind_elem_size * self.cap) as *mut u32;
772            if new_val_ptr.is_null() || new_ind_ptr.is_null() {
773                oom();
774            }
775            self.val_ptr = NonNull::new_unchecked(new_val_ptr);
776            self.ind_ptr = NonNull::new_unchecked(new_ind_ptr);
777        }
778    }
779}
780
781impl<N> Clone for RawZeroSpVec<N> 
782where N: Num
783{
784    #[inline]
785    fn clone(&self) -> Self {
786        unsafe {
787            // If cap == 0 (no allocation) or cap == usize::MAX (ZST marker),
788            // return a dangling-pointer RawZeroSpVec without allocating.
789            if self.cap == 0 || self.cap == usize::MAX {
790                return RawZeroSpVec {
791                    val_ptr: NonNull::dangling(),
792                    ind_ptr: NonNull::dangling(),
793                    cap: self.cap,
794                    _marker: PhantomData,
795                };
796            }
797
798            let val_elem_size = mem::size_of::<N>();
799            let ind_elem_size = mem::size_of::<u32>();
800
801            let t_align = mem::align_of::<N>();
802            let usize_align = mem::align_of::<u32>();
803
804            let new_val_layout = Layout::from_size_align(val_elem_size * self.cap, t_align).expect("Failed to create memory layout");
805            let new_ind_layout = Layout::from_size_align(ind_elem_size * self.cap, usize_align).expect("Failed to create memory layout");
806            let new_val_ptr = alloc(new_val_layout) as *mut N;
807            let new_ind_ptr = alloc(new_ind_layout) as *mut u32;
808            if new_val_ptr.is_null() || new_ind_ptr.is_null() {
809                oom();
810            }
811            ptr::copy_nonoverlapping(self.val_ptr.as_ptr(), new_val_ptr, self.cap);
812            ptr::copy_nonoverlapping(self.ind_ptr.as_ptr(), new_ind_ptr, self.cap);
813
814            RawZeroSpVec {
815                val_ptr: NonNull::new_unchecked(new_val_ptr),
816                ind_ptr: NonNull::new_unchecked(new_ind_ptr),
817                cap: self.cap,
818                _marker: PhantomData,
819            }
820        }
821    }
822}
823
824unsafe impl<N: Num + Send> Send for RawZeroSpVec<N> {}
825unsafe impl<N: Num + Sync> Sync for RawZeroSpVec<N> {}
826
827impl<N> Drop for RawZeroSpVec<N> 
828where N: Num
829{
830    #[inline]
831    fn drop(&mut self) {
832        unsafe {
833            // If no allocation was performed (cap == 0) or this is a ZST marker (usize::MAX), skip deallocation.
834            if self.cap == 0 || self.cap == usize::MAX {
835                return;
836            }
837
838            let val_elem_size = mem::size_of::<N>();
839            let ind_elem_size = mem::size_of::<u32>();
840
841            let t_align = mem::align_of::<N>();
842            let usize_align = mem::align_of::<u32>();
843
844            let new_val_layout = Layout::from_size_align(val_elem_size * self.cap, t_align).expect("Failed to create memory layout");
845            let new_ind_layout = Layout::from_size_align(ind_elem_size * self.cap, usize_align).expect("Failed to create memory layout");
846            dealloc(self.val_ptr.as_ptr() as *mut u8, new_val_layout);
847            dealloc(self.ind_ptr.as_ptr() as *mut u8, new_ind_layout);
848        }
849    }
850}
851
852/// OutOfMemoryへの対処用
853/// プロセスを終了させる
854/// 本来はpanic!を使用するべきだが、
855/// OOMの場合panic!を発生させるとTraceBackによるメモリ仕様が起きてしまうため
856/// 仕方なく強制終了させる
857/// 本来OOMはOSにより管理され発生前にKillされるはずなのであんまり意味はない。
858#[cold]
859fn oom() {
860    ::std::process::exit(-9999);
861}