Example #1
0
// LoadWithOptions loads and executes a javascript file with the ScriptOrigin specified by
// origin and the contents of the file specified by the param code.
func (w *Worker) LoadWithOptions(origin *ScriptOrigin, code string) error {
	cCode := C.CString(code)

	if origin == nil {
		origin = new(ScriptOrigin)
	}
	if origin.ScriptName == "" {
		origin.ScriptName = nextScriptName()
	}
	cScriptName := C.CString(origin.ScriptName)
	cLineOffset := C.int(origin.LineOffset)
	cColumnOffset := C.int(origin.ColumnOffset)
	cIsSharedCrossOrigin := C.bool(origin.IsSharedCrossOrigin)
	cScriptId := C.int(origin.ScriptId)
	cIsEmbedderDebugScript := C.bool(origin.IsEmbedderDebugScript)
	cSourceMapURL := C.CString(origin.SourceMapURL)
	cIsOpaque := C.bool(origin.IsOpaque)

	defer C.free(unsafe.Pointer(cScriptName))
	defer C.free(unsafe.Pointer(cCode))
	defer C.free(unsafe.Pointer(cSourceMapURL))

	r := C.worker_load(w.cWorker, cCode, cScriptName, cLineOffset, cColumnOffset, cIsSharedCrossOrigin, cScriptId, cIsEmbedderDebugScript, cSourceMapURL, cIsOpaque)
	if r != 0 {
		errStr := C.worker_last_exception(w.cWorker)
		return errors.New(C.GoString(errStr))
	}
	return nil
}
Example #2
0
// Open creates options and opens the database. If the database
// doesn't yet exist at the specified directory, one is initialized
// from scratch. The RocksDB Open and Close methods are reference
// counted such that subsequent Open calls to an already opened
// RocksDB instance only bump the reference count. The RocksDB is only
// closed when a sufficient number of Close calls are performed to
// bring the reference count down to 0.
func (r *RocksDB) Open() error {
	if r.rdb != nil {
		return nil
	}

	if r.memtableBudget < minMemtableBudget {
		return util.Errorf("memtable budget must be at least %s: %s",
			humanize.IBytes(minMemtableBudget), humanizeutil.IBytes(r.memtableBudget))
	}

	var ver storageVersion
	if len(r.dir) != 0 {
		log.Infof("opening rocksdb instance at %q", r.dir)

		// Check the version number.
		var err error
		if ver, err = getVersion(r.dir); err != nil {
			return err
		}
		if ver < versionMinimum || ver > versionCurrent {
			// Instead of an error, we should call a migration if possible when
			// one is needed immediately following the DBOpen call.
			return fmt.Errorf("incompatible rocksdb data version, current:%d, on disk:%d, minimum:%d",
				versionCurrent, ver, versionMinimum)
		}
	} else {
		log.Infof("opening in memory rocksdb instance")

		// In memory dbs are always current.
		ver = versionCurrent
	}

	status := C.DBOpen(&r.rdb, goToCSlice([]byte(r.dir)),
		C.DBOptions{
			cache_size:      C.uint64_t(r.cacheSize),
			memtable_budget: C.uint64_t(r.memtableBudget),
			block_size:      C.uint64_t(envutil.EnvOrDefaultBytes("rocksdb_block_size", defaultBlockSize)),
			wal_ttl_seconds: C.uint64_t(envutil.EnvOrDefaultDuration("rocksdb_wal_ttl", 0).Seconds()),
			allow_os_buffer: C.bool(true),
			logging_enabled: C.bool(log.V(3)),
		})
	if err := statusToError(status); err != nil {
		return util.Errorf("could not open rocksdb instance: %s", err)
	}

	// Update or add the version file if needed.
	if ver < versionCurrent {
		if err := writeVersionFile(r.dir); err != nil {
			return err
		}
	}

	// Start a goroutine that will finish when the underlying handle
	// is deallocated. This is used to check a leak in tests.
	go func() {
		<-r.deallocated
	}()
	r.stopper.AddCloser(r)
	return nil
}
Example #3
0
// Open creates options and opens the database. If the database
// doesn't yet exist at the specified directory, one is initialized
// from scratch. The RocksDB Open and Close methods are reference
// counted such that subsequent Open calls to an already opened
// RocksDB instance only bump the reference count. The RocksDB is only
// closed when a sufficient number of Close calls are performed to
// bring the reference count down to 0.
func (r *RocksDB) Open() error {
	if r.rdb != nil {
		atomic.AddInt32(&r.refcount, 1)
		return nil
	}

	if len(r.dir) == 0 {
		log.Infof("opening in-memory rocksdb instance")
	} else {
		log.Infof("opening rocksdb instance at %q", r.dir)
	}
	status := C.DBOpen(&r.rdb, goToCSlice([]byte(r.dir)),
		C.DBOptions{
			cache_size:      C.int64_t(r.cacheSize),
			allow_os_buffer: C.bool(true),
			logging_enabled: C.bool(log.V(3)),
		})
	err := statusToError(status)
	if err != nil {
		return util.Errorf("could not open rocksdb instance: %s", err)
	}

	atomic.AddInt32(&r.refcount, 1)
	return nil
}
Example #4
0
// Open creates options and opens the database. If the database
// doesn't yet exist at the specified directory, one is initialized
// from scratch. The RocksDB Open and Close methods are reference
// counted such that subsequent Open calls to an already opened
// RocksDB instance only bump the reference count. The RocksDB is only
// closed when a sufficient number of Close calls are performed to
// bring the reference count down to 0.
func (r *RocksDB) Open() error {
	if r.rdb != nil {
		return nil
	}

	if len(r.dir) != 0 {
		log.Infof("opening rocksdb instance at %q", r.dir)
	}
	status := C.DBOpen(&r.rdb, goToCSlice([]byte(r.dir)),
		C.DBOptions{
			cache_size:      C.uint64_t(r.cacheSize),
			memtable_budget: C.uint64_t(r.memtableBudget),
			allow_os_buffer: C.bool(true),
			logging_enabled: C.bool(log.V(3)),
		})
	err := statusToError(status)
	if err != nil {
		return util.Errorf("could not open rocksdb instance: %s", err)
	}

	// Start a goroutine that will finish when the underlying handle
	// is deallocated. This is used to check a leak in tests.
	go func() {
		<-r.deallocated
	}()
	r.stopper.AddCloser(r)
	return nil
}
Example #5
0
//export image_progress_callback
func image_progress_callback(goCallback unsafe.Pointer, done C.float) C.bool {
	if goCallback == nil {
		return C.bool(false)
	}

	fn := *(*ProgressCallback)(goCallback)
	cancel := fn(float32(done))
	return C.bool(cancel)
}
Example #6
0
func (r *RocksDB) open() error {
	var ver storageVersion
	if len(r.dir) != 0 {
		log.Infof(context.TODO(), "opening rocksdb instance at %q", r.dir)

		// Check the version number.
		var err error
		if ver, err = getVersion(r.dir); err != nil {
			return err
		}
		if ver < versionMinimum || ver > versionCurrent {
			// Instead of an error, we should call a migration if possible when
			// one is needed immediately following the DBOpen call.
			return fmt.Errorf("incompatible rocksdb data version, current:%d, on disk:%d, minimum:%d",
				versionCurrent, ver, versionMinimum)
		}
	} else {
		if log.V(2) {
			log.Infof(context.TODO(), "opening in memory rocksdb instance")
		}

		// In memory dbs are always current.
		ver = versionCurrent
	}

	blockSize := envutil.EnvOrDefaultBytes("COCKROACH_ROCKSDB_BLOCK_SIZE", defaultBlockSize)
	walTTL := envutil.EnvOrDefaultDuration("COCKROACH_ROCKSDB_WAL_TTL", 0).Seconds()

	status := C.DBOpen(&r.rdb, goToCSlice([]byte(r.dir)),
		C.DBOptions{
			cache:           r.cache.cache,
			block_size:      C.uint64_t(blockSize),
			wal_ttl_seconds: C.uint64_t(walTTL),
			allow_os_buffer: C.bool(true),
			logging_enabled: C.bool(log.V(3)),
			num_cpu:         C.int(runtime.NumCPU()),
			max_open_files:  C.int(r.maxOpenFiles),
		})
	if err := statusToError(status); err != nil {
		return errors.Errorf("could not open rocksdb instance: %s", err)
	}

	// Update or add the version file if needed.
	if ver < versionCurrent {
		if err := writeVersionFile(r.dir); err != nil {
			return err
		}
	}

	// Start a goroutine that will finish when the underlying handle
	// is deallocated. This is used to check a leak in tests.
	go func() {
		<-r.deallocated
	}()
	return nil
}
Example #7
0
// Generic channel shuffling: copy src to dst, but with channels in the order specified by
// ChannelOpts.Order[0..nchannels-1]. Does not support in-place operation.
//
// See ChannelOpts docs for more details on the options.
func Channels(dst, src *ImageBuf, nchannels int, opts ...*ChannelOpts) error {
	var (
		order    *C.int32_t
		values   *C.float
		newNames **C.char
		shuffle  C.bool = C.bool(false)
	)

	var opt *ChannelOpts
	if len(opts) > 0 {
		opt = opts[len(opts)-1]
	}

	if opt != nil {
		shuffle = C.bool(opt.ShuffleNames)

		if opt.Order != nil {
			if len(opt.Order) < nchannels {
				return fmt.Errorf("ChannelOpts.Order length %d is less than nchannels %d",
					len(opt.Order), nchannels)
			}
			order = (*C.int32_t)(unsafe.Pointer(&opt.Order[0]))
		}

		if opt.Values != nil {
			if len(opt.Values) < nchannels {
				return fmt.Errorf("ChannelOpts.Values length %d is less than nchannels %d",
					len(opt.Values), nchannels)
			}
			values = (*C.float)(unsafe.Pointer(&opt.Values[0]))
		}

		if opt.NewNames != nil {
			if len(opt.NewNames) < nchannels {
				return fmt.Errorf("ChannelOpts.NewNames length %d is less than nchannels %d",
					len(opt.NewNames), nchannels)
			}
			nameSize := len(opt.NewNames)
			newNames = C.makeCharArray(C.int(nameSize))
			defer C.freeCharArray(newNames, C.int(nameSize))
			for i, s := range opt.NewNames {
				C.setArrayString(newNames, C.CString(s), C.int(i))
			}
		}
	}

	ok := C.channels(dst.ptr, src.ptr, C.int(nchannels), order, values, newNames, shuffle)
	if !bool(ok) {
		return dst.LastError()
	}
	return nil
}
Example #8
0
// Create a C struct to hold the Tox client startup options. This struct
// contains C heap items that must be freed to prevent memory leaks.
func (options *ToxOptions) cOptions() (c_options *C.struct_Tox_Options) {
	// Initialize the return object.
	c_options = &C.struct_Tox_Options{}
	// Copy the fields.
	c_options.ipv6_enabled = C.bool(options.IPv6Enabled)
	c_options.udp_enabled = C.bool(options.UDPEnabled)
	c_options.proxy_type = C.TOX_PROXY_TYPE(options.ProxyType)
	c_options.proxy_host = C.CString(options.ProxyHost)
	c_options.proxy_port = C.uint16_t(options.ProxyPort)
	c_options.start_port = C.uint16_t(options.StartPort)
	c_options.end_port = C.uint16_t(options.EndPort)
	return
}
Example #9
0
// Restore restores the container from a checkpoint.
func (c *Container) Restore(opts RestoreOptions) error {
	if err := c.makeSure(isGreaterEqualThanLXC11); err != nil {
		return err
	}

	cdirectory := C.CString(opts.Directory)
	defer C.free(unsafe.Pointer(cdirectory))

	cverbose := C.bool(opts.Verbose)

	if !C.bool(C.go_lxc_restore(c.container, cdirectory, cverbose)) {
		return ErrRestoreFailed
	}
	return nil
}
Example #10
0
// Checkpoint checkpoints the container.
func (c *Container) Checkpoint(opts CheckpointOptions) error {
	if err := c.makeSure(isRunning | isGreaterEqualThanLXC11); err != nil {
		return err
	}

	cdirectory := C.CString(opts.Directory)
	defer C.free(unsafe.Pointer(cdirectory))

	cstop := C.bool(opts.Stop)
	cverbose := C.bool(opts.Verbose)

	if !C.go_lxc_checkpoint(c.container, cdirectory, cstop, cverbose) {
		return ErrCheckpointFailed
	}
	return nil
}
Example #11
0
// Delete a key
func (client *Client) Delete(key string) error {
	client.lock()
	defer client.unlock()

	rawKey := client.addPrefix(key)

	cKey := C.CString(rawKey)
	defer C.free(unsafe.Pointer(cKey))
	cKeyLen := C.size_t(len(rawKey))
	cNoreply := C.bool(client.noreply)

	var rst **C.message_result_t
	var n C.size_t

	errCode := C.client_delete(
		client._imp, &cKey, &cKeyLen, cNoreply, 1, &rst, &n,
	)
	defer C.client_destroy_message_result(client._imp)

	if errCode == 0 {
		if client.noreply {
			return nil
		} else if int(n) == 1 && ((*rst).type_ == C.MSG_DELETED || (*rst).type_ == C.MSG_NOT_FOUND) {
			return nil
		}
	}

	return errors.New(errorMessage[errCode])
}
Example #12
0
// make is needed to create types for use by test
func makevalue(v interface{}) (UnionSassValue, error) {
	f := reflect.ValueOf(v)
	err := error(nil)
	switch f.Kind() {
	default:
		return C.sass_make_null(), err
	case reflect.Bool:
		return C.sass_make_boolean(C.bool(v.(bool))), err
	case reflect.String:
		return C.sass_make_string(C.CString(v.(string))), err
	case reflect.Struct: //only SassNumber and color.RGBA are supported
		if reflect.TypeOf(v).String() == "context.SassNumber" {
			var sn = v.(SassNumber)
			return C.sass_make_number(C.double(sn.Value), C.CString(sn.Unit)), err
		} else if reflect.TypeOf(v).String() == "color.RGBA" {
			var sc = v.(color.RGBA)
			return C.sass_make_color(C.double(sc.R), C.double(sc.G), C.double(sc.B), C.double(sc.A)), err
		} else {
			err = errors.New(fmt.Sprintf("The struct type %s is unsupported for marshalling", reflect.TypeOf(v).String()))
			return C.sass_make_null(), err
		}
	case reflect.Slice:
		// Initialize the list
		l := C.sass_make_list(C.size_t(f.Len()), C.SASS_COMMA)
		for i := 0; i < f.Len(); i++ {
			t, er := makevalue(f.Index(i).Interface())
			if err == nil && er != nil {
				err = er
			}
			C.sass_list_set_value(l, C.size_t(i), t)
		}
		return l, err
	}
}
Example #13
0
// Processes the accumulated input data and returns the new output meta-block,
// or zero if no new output meta-block was created (in this case the processed
// input data is buffered internally).
// Returns ErrInputLargerThanBlockSize if more data was copied to the ring buffer
// than the block sized.
// If isLast or forceFlush is true, an output meta-block is always created
func (bp *brotliCompressor) writeBrotliData(isLast bool, forceFlush bool) ([]byte, error) {
	var outSize C.size_t
	var output *C.uint8_t
	success := C.CBrotliCompressorWriteBrotliData(bp.c, C.bool(isLast), C.bool(forceFlush), &outSize, &output)
	if success == false {
		return nil, errInputLargerThanBlockSize
	}

	// resize buffer if output is larger than we've anticipated
	if int(outSize) > cap(bp.outputBuffer) {
		bp.outputBuffer = make([]byte, int(outSize))
	}

	C.memcpy(unsafe.Pointer(&bp.outputBuffer[0]), unsafe.Pointer(output), outSize)
	return bp.outputBuffer[:outSize], nil
}
Example #14
0
// Delete a key
func (client *Client) Delete(key string) error {
	client.lock()
	defer client.unlock()

	rawKey := client.addPrefix(key)

	cKey := C.CString(rawKey)
	defer C.free(unsafe.Pointer(cKey))
	cKeyLen := C.size_t(len(rawKey))
	cNoreply := C.bool(client.noreply)

	var rst **C.message_result_t
	var n C.size_t

	errCode := C.client_delete(
		client._imp, &cKey, &cKeyLen, cNoreply, 1, &rst, &n,
	)
	defer C.client_destroy_message_result(client._imp)

	if errCode == 0 {
		if client.noreply {
			return nil
		} else if int(n) == 1 {
			if (*rst).type_ == C.MSG_DELETED {
				return nil
			} else if (*rst).type_ == C.MSG_NOT_FOUND {
				return ErrCacheMiss
			}
		}
	} else if errCode == C.RET_INVALID_KEY_ERR {
		return ErrMalformedKey
	}

	return networkError(errorMessage[errCode])
}
Example #15
0
// Equal checks two Certs for equality
func (c *Cert) Equal(compare *Cert) bool {
	check := C.zcert_eq(c.zcertT, compare.zcertT)
	if check == C.bool(true) {
		return true
	}
	return false
}
Example #16
0
// Keypad turns on/off the keypad characters, including those like the F1-F12
// keys and the arrow keys
func (w *Window) Keypad(keypad bool) error {
	var err C.int
	if err = C.keypad(w.win, C.bool(keypad)); err == C.ERR {
		return errors.New("Unable to set keypad mode")
	}
	return nil
}
Example #17
0
// Touch command
func (client *Client) Touch(key string, expiration int64) error {
	client.lock()
	defer client.unlock()

	rawKey := client.addPrefix(key)

	cKey := C.CString(rawKey)
	defer C.free(unsafe.Pointer(cKey))
	cKeyLen := C.size_t(len(rawKey))
	cExptime := C.exptime_t(expiration)
	cNoreply := C.bool(client.noreply)

	var rst **C.message_result_t
	var n C.size_t

	errCode := C.client_touch(
		client._imp, &cKey, &cKeyLen, cExptime, cNoreply, 1, &rst, &n,
	)
	defer C.client_destroy_message_result(client._imp)

	if errCode == 0 {
		if client.noreply {
			return nil
		} else if int(n) == 1 && (*rst).type_ == C.MSG_TOUCHED {
			return nil
		}
	}
	return errors.New(errorMessage[errCode])
}
Example #18
0
func (c *Config) SetStrictParsingEnabled(enabled bool) error {
	_, err := C.Config_setStrictParsingEnabled(c.ptr, C.bool(enabled))
	if err != nil {
		return c.lastError()
	}
	return err
}
Example #19
0
// This routine will return the error string (and clear any error
// flags).  If no error has occurred since the last time GetError()
// was called, it will return an empty string.
func (c *ColorConfig) error() error {
	isError := C.ColorConfig_error(c.ptr)
	if C.bool(isError) {
		return errors.New(C.GoString(C.ColorConfig_geterror(c.ptr)))
	}
	return nil
}
Example #20
0
/* Enables the reading of all keys on a keyboard (that the operating system will interpret) */
func Keypad(win *Window, translate bool) {
	temp := 0
	if translate {
		temp = 1
	}
	C.keypad((*C.WINDOW)(win), C.bool(temp))
}
Example #21
0
// Creates new SSL connection for the underlying reader and writer.
func NewConn(reader io.Reader, writer io.Writer,
	config *Config, server bool) (*Conn, error) {
	c := &Conn{}

	if server && (config.Cert == nil || config.PrivateKey == nil) {
		panic("Cert and PrivateKey are required for server SSL connections")
	}

	sslConnConfig := newSSLConnConfig(config)
	defer cleanupSSLConnConfig(sslConnConfig)
	sslConnConfig.is_server = C.bool(server)
	sslConnConfig.ptr = unsafe.Pointer(c)

	var sslConnError C.SSLConnError
	c.sslConn = C.SSLConn_new(sslConnConfig,
		(*C.SSLConnError)(unsafe.Pointer(&sslConnError)))
	if c.sslConn == nil {
		return nil, errors.New(C.GoString(&sslConnError.string[0]))
	}

	c.lock = &sync.Mutex{}
	c.reader = NewNonBlockingReader(reader, defaultBufferSize)
	c.writer = NewNonBlockingWriter(writer, defaultBufferSize)
	return c, nil
}
Example #22
0
func scan(tryhard bool, stride int, pixels []uint8) ([]string, error) {
	outputs := make([]*C.char, 8)
	count, e := C.scan(
		C.bool(tryhard),
		C.int(stride),
		C.int(len(pixels)),
		(*C.char)(unsafe.Pointer(&pixels[0])),
		C.int(len(outputs)),
		&outputs[0],
	)

	if e != nil {
		return nil, e
	}

	results := make([]string, 0, count)
	for i := 0; i < int(count); i++ {
		str := C.GoString(outputs[i])
		results = append(results, str)

		C.free(unsafe.Pointer(outputs[i]))
	}

	return results, nil
}
Example #23
0
// Configure the will message. Must be called before Connect().
func (client *MosquittoClient) SetWillMessage(topic string, payload []byte, qos int, retain bool) error {
	ctopic := C.CString(topic)
	defer C.free(unsafe.Pointer(ctopic))
	m := (*C.struct_mosquitto)(client.instance)
	status := C.mosquitto_will_set(m, ctopic, C.int(len(payload)),
		unsafe.Pointer(&payload[0]), C.int(qos), C.bool(retain))
	return Errno(status)
}
Example #24
0
// Publish a byte array message
func (client *MosquittoClient) Publish(messageId uint, topic string, payload []byte, qos int, retain bool) error {
	m := (*C.struct_mosquitto)(client.instance)
	cmsgId := C.int(messageId)
	ctopic := C.CString(topic)
	status := C.mosquitto_publish(m, &cmsgId, ctopic,
		C.int(len(payload)), unsafe.Pointer(&payload[0]), C.int(qos), C.bool(retain))
	return Errno(status)
}
Example #25
0
func messageProcess(private *keys.PrivateKey, peerPublic *keys.PublicKey, message []byte, is_wrap bool) ([]byte, error) {
	if nil == message {
		return nil, errors.New("No message was provided")
	}

	var priv, pub unsafe.Pointer
	var privLen, pubLen C.size_t

	if nil != private {
		priv = unsafe.Pointer(&private.Value[0])
		privLen = C.size_t(len(private.Value))
	}

	if nil != peerPublic {
		pub = unsafe.Pointer(&peerPublic.Value[0])
		pubLen = C.size_t(len(peerPublic.Value))
	}

	var output_length C.size_t
	if !bool(C.get_message_size(priv,
		privLen,
		pub,
		pubLen,
		unsafe.Pointer(&message[0]),
		C.size_t(len(message)),
		C.bool(is_wrap),
		&output_length)) {
		return nil, errors.New("Failed to get ouput size")
	}

	output := make([]byte, int(output_length), int(output_length))
	if !bool(C.process(priv,
		privLen,
		pub,
		pubLen,
		unsafe.Pointer(&message[0]),
		C.size_t(len(message)),
		C.bool(is_wrap),
		unsafe.Pointer(&output[0]),
		output_length)) {
		return nil, errors.New("Failed to wrap message")
	}

	return output, nil
}
Example #26
0
func newRocksDBBatch(parent *RocksDB, writeOnly bool) *rocksDBBatch {
	r := &rocksDBBatch{
		parent:    parent,
		batch:     C.DBNewBatch(parent.rdb, C.bool(writeOnly)),
		writeOnly: writeOnly,
	}
	r.distinct.rocksDBBatch = r
	return r
}
Example #27
0
// WantCloseAllFds determines whether container wishes all file descriptors
// to be closed on startup.
func (c *Container) WantCloseAllFds(state bool) error {
	c.mu.Lock()
	defer c.mu.Unlock()

	if !bool(C.go_lxc_want_close_all_fds(c.container, C.bool(state))) {
		return ErrCloseAllFdsFailed
	}
	return nil
}
Example #28
0
// Set dst, over the region of interest, to be a resampled version of the corresponding portion of src
// (mapping such that the "full" image window of each correspond to each other, regardless of resolution).
// Unlike Resize(), Resample does not take a filter; it just samples either with a bilinear
// interpolation (if interpolate is true, the default) or uses the single "closest" pixel (if interpolate is false).
// This makes it a lot faster than a proper Resize(), though obviously with lower quality (aliasing when downsizing,
// pixel replication when upsizing).
// Works on all pixel data types.
func Resample(dst, src *ImageBuf, interpolate bool, opts ...AlgoOpts) error {
	opt := flatAlgoOpts(opts)

	ok := C.resample(dst.ptr, src.ptr, C.bool(interpolate), opt.ROI.validOrAllPtr(), C.int(opt.Threads))
	if !bool(ok) {
		return dst.LastError()
	}
	return nil
}
Example #29
0
// Enables colors to be displayed. Will return an error if terminal is not
// capable of displaying colors
func StartColor() error {
	if C.has_colors() == C.bool(false) {
		return errors.New("Terminal does not support colors")
	}
	if C.start_color() == C.ERR {
		return errors.New("Failed to enable color mode")
	}
	return nil
}
Example #30
0
// newRocksDBIterator returns a new iterator over the supplied RocksDB
// instance. If snapshotHandle is not nil, uses the indicated snapshot.
// The caller must call rocksDBIterator.Close() when finished with the
// iterator to free up resources.
func newRocksDBIterator(rdb *C.DBEngine, prefix bool) *rocksDBIterator {
	// In order to prevent content displacement, caching is disabled
	// when performing scans. Any options set within the shared read
	// options field that should be carried over needs to be set here
	// as well.
	return &rocksDBIterator{
		iter: C.DBNewIter(rdb, C.bool(prefix)),
	}
}