I am trying to write a global fn for my cat system that is in the base controller.
here is the fn inside the base cont
public function rec_cat($table,$col,$col_id,$rec_arr=array()) {
$ups=DB::table($table)->where($col,$col_id)->get();
foreach ($ups as $up) {
$rec_arr[]=$up;
$this->rec_cat($table,$col,$col_id,$rec_arr);
}
return $rec_arr;
}
when I try to call this fn in my controller
$select=$this->rec_cat('kategori','up_id','0');
return var_dump($select);
I get this error
Allowed memory size of 134217728 bytes exhausted (tried to allocate 196605 bytes)
The bytes written in the error is smaller than the allowed memory size so I think I have another problem.
Any suggestions?
You have an infinite loop in your function, it just keeps calling itself over and over again until you run out of memory.
I cant tell what you are trying to do, but you are just calling the same function with the same variables each time.
You need to be supplying new variables on each recursive call..
Related
I have a function with following declaration:
fn find_solutions_internal<'a, I>(&self, words: I, iterate_from: usize, chain: &mut Vec<u32>)
where I: Iterator<Item=&'a u32> + Clone;
Because the function recursively iterates over the same vector (max-depth of recursion is 5) with different filters I decided that it would be more effecient to pass the iterator as an argument.
Following part of code causes error:
let iterator = words.skip(iterate_from).filter(|&mask| mask & last_mask == 0);
let filtered_words = iterator.clone();
iterator.enumerate().for_each(|(i, &mask)| {
chain.push(mask);
self.find_solutions_internal(filtered_words.clone(), i, chain); // filtered_words.clone() is what indirectly causes the error
chain.pop();
});
The error:
error: reached the recursion limit while instantiating `<std::iter::Filter<std::iter::Sk...]>::{closure#0}]>::{closure#0}]>`
115 | self.iter.fold(init, fold)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `<std::iter::Filter<I, P> as Iterator>::fold` defined here
...
Self-contained example of the problematic code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ada8578f166ad2a34373d82cc376921f
Working example with collected iteration to vector: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=4c13d2d0ac17038dac61c9e2d59bbab5
As #Jmb commented, the compiler does not try figuring out how many times the function recurses, at least not for the purpose of allowing this kind of code to compile. The compiler assumes each call to find_solutions_internal() can potentially recurse, and so the compiler gets stuck repeatedly instantiating the function, as each recursive call has a unique iterator parameter type.
We can fix this problem by passing the iterator as a trait object when making the recursive call, though the fact that we're cloning the iterator complicates things, as the Clone trait doesn't work with trait objects. We can work around that with the dyn_clone crate, at the cost of some boilerplate.
First we define a clonable iterator trait:
use dyn_clone::DynClone;
trait ClonableIterator<T>: Iterator<Item = T> + DynClone {}
impl<I, T> ClonableIterator<T> for I where I: Iterator<Item = T> + DynClone {}
dyn_clone::clone_trait_object!(<T> ClonableIterator<T>);
Then in the recursive call we construct the trait object:
self.find_solutions_internal(
Box::new(filtered_words.clone()) as Box<dyn ClonableIterator<_>>,
i,
chain,
);
While the above solution works, I think it'll likely end up slower than doing the simple thing of just collecting into a Vec. If the vector is really big, using a datastructure like Vector from the im crate, which supports O(1) cloning and O(log n) remove might be faster.
I'm currently trying to write a function that is generally equivalent to numpy's tile. Currently each time I try to return a (altered or unaltered) clone of the input array, I get a warning about an overflow, and cargo prompts me to increase the recursion limit. however this function isn't recursive, so I'm assuming its happening somewhere in the implementation.
here is the stripped down function, (full version):
pub fn tile<A, D1, D2>(arr: &Array<A, D1>, reps: Vec<usize>) -> Array<A, D2>
where
A: Clone,
D1: Dimension,
D2: Dimension,
{
let num_of_reps = reps.len();
//just clone the array if reps is all ones
let mut res = arr.clone();
let bail_flag = true;
for &x in reps.iter() {
if x != 1 {
bail_flag = false;
}
}
if bail_flag {
let mut res_dim = res.shape().to_owned();
_new_shape(num_of_reps, res.ndim(), &mut res_dim);
res.to_shape(res_dim);
return res;
}
...
//otherwise do extra work
...
return res.reshape(shape_out);
}
this is the actual error I'm getting on returning res:
overflow evaluating the requirement `&ArrayBase<_, _>: Neg`
consider increasing the recursion limit by adding a `#![recursion_limit = "1024"]` attribute to your crate (`mfcc_2`)
required because of the requirements on the impl of `Neg` for `&ArrayBase<_, _>`
511 redundant requirements hidden
required because of the requirements on the impl of `Neg` for `&ArrayBase<OwnedRepr<A>, D1>`rustcE0275
I looked at the implementation of Neg in ndarray, it doesn't seem to be recursive, so I'm a little confused as to what is going on.
p.s. I'm aware there are other errors in this code, as those appeared after I switched from A to f64(the actual type I plan on using the function with), but those are mostly trivial to fix. Still if you have suggestions on any error you see I appreciate them nonetheless.
I'm trying to debug why my device isn't being recognized on my MacOS BigSur laptop in Rust. I've ran my Python code to verify that it exists, though it's unable to be read to which is very strange. As Rust has the serial port library and it seems a lot more robust than PyUSB I decided to use it.
The code I'm using is taken from a pre-existing project that worked on x86_64 processors, Big Sur using Apples M1 chip.
Here's the code:
#[cfg(not(feature = "fake_serial"))]
pub fn start_serial_probe(
custom_tty: &Option<String>,
// ) -> Result<crossbeam_channel::Receiver<B0xxMessage>, ViewerError> {
) {
let b0xx_port = serialport::available_ports();
for port in &b0xx_port {
// let port : serialport::SerialPortInfo = port;
println!("{} ", port.port_name);
}
...
The error when compiling is the same as what I'm receiving in VSCode.
no field port_name on type &std::vec::Vec<serialport::SerialPortInfo>
I'm not entirely sure how to grab the items through the vector, as most use integers, etc in some type of array.
Thanks!
The function serialport::available_ports() returns a Result<Vec<SerialialPortInfo>>, not a Vec<SerialPortInfo>.
The confusion here is likely because Result implements IntoIterator, and looping over it will yield either one or zero elements depending on if it is Ok or Err respectively. The item is a Vec in this case, which is why you can't access fields of SerialialPortInfo.
This should work:
if let Ok(b0xx_port) = serialport::available_ports() {
for port in &b0xx_port {
println!("{} ", port.port_name);
}
} else {
// handle the error
}
I'm calling next multiple times on a Stream returned by this function: https://github.com/sdroege/rtsp-server/blob/96dbaf00a7111c775348430a64d6a60f16d66445/src/listener/message_socket.rs#L43:
pub(crate) fn async_read<R: AsyncRead + Unpin + Send>(
read: R,
max_size: usize,
) -> impl Stream<Item = Result<Message<Body>, ReadError>> + Send {
//...
futures::stream::unfold(Some(state), move |mut state| async move {
//...
})
}
sometimes it works, but sometimes I get:
thread 'main' panicked at 'Unfold must not be polled after it returned `Poll::Ready(None)`', /root/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-0.3.13/src/stream/unfold.rs:115:21
The error comes from https://docs.rs/futures-util/0.3.2/src/futures_util/stream/unfold.rs.html#112
but I couldn't understand why. Shouldn't I be free to call next on a Stream, in a loop?
This error is an error for a reason, as it likely means that you are doing something wrong: when a stream returns Poll::Ready(None), it means that the stream is completed (in a similar fashion to Iterator, as has been commented).
However, if you are still sure that this is what you want to do, then you can call stream.fuse() in order to silence the error and simply return Poll::Ready(None) forever.
Snippet: An external C dll which receives a collection(Nested Table of numbers) from PLSQL and does some processing(not shown in the code).
Issue: When this external C function is called from PLSQL(library and wrapper created in PLSQL) the numbers are received by the C function in the array(on stack). HOWEVER, if I un-comment the commented lines for a dynamic array(on Heap) instead of a static the call fails with:
ORA-28579: network error during callback from external procedure agent.
Please suggest
#define ARRSIZE 107
extern "C" __declspec(dllexport) int ooci_ntm(OCIExtProcContext *context, OCITable* clients)
{
OCIEnv *envhp;
OCISvcCtx* svch;
OCIError *errhp;
double onumm[ARRSIZE]; //Works if its a static array on stack
//double* onumm= (double*)malloc(sizeof(double) * ARRSIZE);
//However, if instead of the above array if the memory is allocated dynamically on heap then the captioned error is thrown.
sword status;
boolean exist;
uword nelems;
OCIExtProcGetEnv (context, &envhp, &svch, &errhp);
OCINumber **client_elem = (OCINumber**)malloc(sizeof(OCINumber*) * ARRSIZE);
status = OCICollGetElemArray(envhp, errhp, clients, index, &exist, (void**)client_elem, (dvoid **)0, &nelems);
status = OCINumberToRealArray(errhp,(const OCINumber**)client_elem,nelems,sizeof(double),(void*)onumm);
free(client_elem);
//free(onumm);
return size;
}
It looks like this is one of those errors that essentially means any number of things could have gone wrong with the external procedure.
There is a known bug in 10.2.0.3, no idea if it's relevant:
ORA-28579 occurs when trying to select
data from a pipelined table function
implemented in "C" using the
ODCITable/ANYDATASET interface.
ODCITableDescribe works fine but
ODCITableFetch generates an ORA-28579
error.
Try to Contact Oracle support