No description
Find a file
Seebs c133ce0376 Make containers copy-on-write
This patch replaces a lot of circumstances in which containers
were being copied with circumstances in which they are shared,
using copy-on-write semantics.

To achieve this, we emulate somewhat the design of go's
native `append` function. Operations on a container may optionally
yield a new container. A container can be marked "frozen",
after which no operation should ever write to it in any way;
that applies both to the container itself and the backing store
it refers to, if any. So for instance, instead of:

	c.arrayToBitmap()

we now write:

	c = c.arrayToBitmap()

Operations which need to modify a container in any way
need to be able to return a new container, which is a modified
copy of the previous container. This applies to operations
like add/remove, but also to things like unmapping memory-mapped
storage, or changing a container's type.

Bitmaps do not support the same copy-on-write semantics,
currently, but "copying" a bitmap and sharing the containers
instead of duplicating them is *much* cheaper than copying
the containers.

Bitmaps do support a .Freeze method, which currently copies
the previous bitmap, making a new one with the same container
pointers, and freezes the individual containers. Use this
if you need a writeable copy of a bitmap -- the resulting
bitmap can safely have its set of containers modified, and
bitmap operators that would want to modify the containers
will use copy-on-write for that.

The primary motivation of this is to reduce the cost of the
row cache used by fragments. As a secondary issue, the row cache
is no longer updated on writes -- that update was actually a
race condition waiting to happen. Rather, writes to a row
invalidate the cache entry for that row. The row cache is
created by creating a new bitmap, and freezing the relevant
containers from the fragment's storage. In the case where
nothing is being written, the row cache grows to contain
bitmaps containing all those containers, but never copies
any containers. If nothing's being read, the row cache is
never created, and the containers are in general not getting
frozen. The only circumstance where copies have to happen is
when things are read (and thus stored in the row cache) and
later modified. In that case, each read freezes objects, and
the first write to a container after it's been frozen will
create a new copy.

We drop the enterprise/b btree implementation, because we
don't really need it anymore -- we now provide that
implementation by default in the open source product anyway.

Along with this, there's a lot of other changes which
improve support for nil containers, as a cheaper representation
for empty containers. Operations which we know will provide
an empty container can always short-circuit and just yield
a nil *Container. Similarly, operations which would provide
a full container can return a single shared full container
object (which is frozen). The higher-level (non type-specific)
container ops are now using that logic to short-circuit
operations for empty and full containers. (For instance,
difference of anything minus an empty container is the
original thing, union of anything and empty is the original
thing, and so on.)

The Containers interface adds "Update" and "UpdateEvery"
methods, based in part on the "Put" interface provided
by the underlying btree implementation; Update performs
a possible update in-place of a container for a given
key, bypassing the need to replicate the search for that
key in the container. UpdateEvery loops through all the
containers.

Containers do not strictly guarantee that they won't
return nil `*Container` objects. However, the container
iterators won't return those -- empty containers aren't
interesting. Some tests are updated to reflect this.

Some of the container internals, like N(), or the isArray()
and related functions, accept nil container pointers. Some,
like Thaw(), do not. For the array(), bitmap(), and runs()
methods, roaringparanoia enables an explicit panic on a nil
container explaining the problem, but the intent is that those
should never be called unless you already know you have the
right kind of container, so by default they don't perform
the extra checks. In most cases, this is already covered
because a nil container is empty, and there's no operation
we can perform that requires us to inspect the contents of
an empty container. This is passing a fair amount of testing,
but the testing may not be comprehensive enough.

The overall impact of this is pretty trivial performance-wise.
In our default roaring/ benchmarks, a few things get a few
percent faster, or slower. The advantage is that, with
read-heavy workloads, the row cache no longer eats up incredible
amounts of memory.

For a smallish test case, pilosa's memory usage (RES in top) after
startup was ~2.5GB. Without this patch, simply reading every
row a few times got memory usage to about 9GB, which seemed
reasonably stable. With this patch, memory usage went to about
3GB. This will be less noticeable in mixed read/write loads,
but it should be consistently significantly lower.

In addition to dropping things from the rowCache on modifications,
we also stopped performing a full count on a modified row when
not using a cache of a kind that would use that count, and don't
repopulate the rowCache regardless. We don't want every write
to imply a corresponding read after it.

There's a lot of room for possible future optimizations in
terms of things like in-place operations, and some of the
row/rowSegment code is a little suspicious to me, but I don't
think it should be *worse* in any cases.
2019-05-30 16:36:20 -05:00
.circleci don't call the golangci-lint workflow anymore 2019-04-16 12:08:40 -05:00
.github Add changelog steps to PR template 2019-04-12 13:47:40 -05:00
boltdb address meta-lint or half-baked lint fixes 2019-04-16 12:08:40 -05:00
cmd address meta-lint or half-baked lint fixes 2019-04-16 12:08:40 -05:00
ctl send POSTed schema to all nodes in cluster 2019-04-29 19:31:23 -05:00
docs Unbounded BSI w/ sign magnitude 2019-05-17 15:52:17 -06:00
encoding/proto Add min/max constraints; fix tests 2019-05-19 16:05:22 -06:00
enterprise drop enterprise/b 2019-05-30 16:36:20 -05:00
gcnotify Unexport gcnotify.ActiveGCNotifier 2018-07-05 23:11:56 -05:00
gopsutil so much lint 2019-04-16 12:07:18 -05:00
gossip Advertise address and listen on 0.0.0.0 2019-01-21 22:36:55 -06:00
http make linter happy 2019-05-28 14:12:04 +03:00
inmem Add license headers to files missing them and CI check to verify they are present. Fixes #1633 2019-04-12 11:30:41 -05:00
internal Add min/max constraints 2019-05-17 15:52:17 -06:00
logger so much lint 2019-04-16 12:07:18 -05:00
lru so much lint 2019-04-16 12:07:18 -05:00
mock Add license headers to files missing them and CI check to verify they are present. Fixes #1633 2019-04-12 11:30:41 -05:00
pql added check for unexpected parser error 2019-05-15 12:11:55 -05:00
roaring Make containers copy-on-write 2019-05-30 16:36:20 -05:00
server fix int min max test for 32bit 2019-05-28 14:25:46 +03:00
shardwidth Fix enterprise license header and add shardwidth files to license header check 2019-04-12 11:57:28 -05:00
stats send POSTed schema to all nodes in cluster 2019-04-29 19:31:23 -05:00
statsd move Logger and Stats to their own packages 2018-11-15 15:10:44 -06:00
syswrap Add license headers to files missing them and CI check to verify they are present. Fixes #1633 2019-04-12 11:30:41 -05:00
test send POSTed schema to all nodes in cluster 2019-04-29 19:31:23 -05:00
testdata/sample_view Adds fragment test data, implements #1090 2018-05-01 17:28:10 +03:00
toml Add license headers to files missing them and CI check to verify they are present. Fixes #1633 2019-04-12 11:30:41 -05:00
tracing Add license headers to files missing them and CI check to verify they are present. Fixes #1633 2019-04-12 11:30:41 -05:00
.gitignore Hide build directory in .gitignore 2017-05-19 14:17:57 -05:00
api.go added test for 1977 fix 2019-05-28 13:54:12 +03:00
api_test.go Add min/max constraints; fix tests 2019-05-19 16:05:22 -06:00
apimethod_string.go send POSTed schema to all nodes in cluster 2019-04-29 19:31:23 -05:00
attr.go Add distributed tracing. 2018-11-21 15:08:33 -06:00
attr_test.go Fix linter issues: staticcheck (covered by megacheck, along with gosimple and unused) 2018-07-20 11:19:24 -05:00
broadcast.go Fix linter issues: gochecknoinits 2018-07-18 11:58:27 -05:00
cache.go Make containers copy-on-write 2019-05-30 16:36:20 -05:00
cache_test.go account for all same values in rank 2017-08-28 13:46:18 -05:00
CHANGELOG.md Release v1.3.0 2019-04-16 14:38:33 -05:00
client.go send POSTed schema to all nodes in cluster 2019-04-29 19:31:23 -05:00
cluster.go fix some lint warnings raised in VS-Code 2019-04-17 18:10:05 -05:00
cluster_internal_test.go address meta-lint or half-baked lint fixes 2019-04-16 12:08:40 -05:00
cmd.go Apply Apache License 2.0 2017-04-28 14:22:03 -05:00
CONTRIBUTING.md simplify contributing instructions by removing weird upstream thing 2019-05-01 17:37:52 -05:00
diagnostics.go fix some lint warnings raised in VS-Code 2019-04-17 18:10:05 -05:00
diagnostics_internal_test.go so much lint 2019-04-16 12:07:18 -05:00
doc.go Apply Apache License 2.0 2017-04-28 14:22:03 -05:00
Dockerfile Release v1.3.0 2019-04-16 14:38:33 -05:00
Dockerfile-clustertests Add go module support 2019-01-29 14:53:03 -06:00
event.go fix some lint warnings raised in VS-Code 2019-04-17 18:10:05 -05:00
executor.go Improve TopN() errors 2019-05-25 15:16:45 -06:00
executor_internal_test.go Add license headers to files missing them and CI check to verify they are present. Fixes #1633 2019-04-12 11:30:41 -05:00
executor_test.go Improve TopN() errors 2019-05-25 15:16:45 -06:00
field.go fixes #1977 2019-05-27 17:43:53 +03:00
field_internal_test.go Add min/max constraints 2019-05-17 15:52:17 -06:00
field_test.go Add min/max constraints; fix tests 2019-05-19 16:05:22 -06:00
fragment.go Make containers copy-on-write 2019-05-30 16:36:20 -05:00
fragment_internal_test.go Make containers copy-on-write 2019-05-30 16:36:20 -05:00
gc.go fix some lint warnings raised in VS-Code 2019-04-17 18:10:05 -05:00
go.mod Merge branch 'master' into reopen 2019-05-03 01:11:15 +02:00
go.sum fixed error message returned by regex on field and index names 2019-05-14 11:57:07 -05:00
handler.go fix some lint warnings raised in VS-Code 2019-04-17 18:10:05 -05:00
holder.go remove shard validation stuff 2019-04-22 17:36:40 -05:00
holder_internal_test.go so much lint 2019-04-16 12:07:18 -05:00
holder_test.go so much lint 2019-04-16 12:07:18 -05:00
index.go add more Debugf() statements to the holder open process 2019-04-30 15:16:10 -05:00
index_internal_test.go make sure more tests and benchmarks can have their temp dir set by flag 2019-01-21 16:23:27 -06:00
index_test.go Add min/max constraints; fix tests 2019-05-19 16:05:22 -06:00
iterator.go Fix linter issues: unparam 2018-07-17 12:05:07 -05:00
iterator_internal_test.go rename internal_tests. fix license header 2018-07-04 10:59:08 -05:00
LICENSE Apply Apache License 2.0 2017-04-28 14:22:03 -05:00
Makefile try suppressing modules for golangci-lint 2019-04-16 12:06:28 -05:00
NOTES rename slice to shard 2018-06-28 14:07:07 -05:00
NOTICE update licensing and NOTICE to reflect btree being moved to roaring 2019-03-05 15:52:32 -06:00
pilosa.go Add min/max constraints; fix tests 2019-05-19 16:05:22 -06:00
pilosa_internal_test.go change exists field to _exists 2018-12-17 15:44:50 -06:00
pilosa_test.go un-export some top-level functions 2018-06-13 16:44:24 -05:00
README.md Remove TravisCI, add CircleCI shield 2018-11-13 12:34:44 -06:00
row.go Make containers copy-on-write 2019-05-30 16:36:20 -05:00
row_test.go a quicker empty check for group by 2019-01-02 14:32:59 -06:00
server.go remove shard validation stuff 2019-04-22 17:36:40 -05:00
server_internal_test.go remove shard validation stuff 2019-04-22 17:36:40 -05:00
time.go add logic to restrict time range to available views 2019-02-01 15:30:10 -06:00
time_internal_test.go add logic to restrict time range to available views 2019-02-01 15:30:10 -06:00
translate.go TranslateFile - reopen the same instance 2019-05-02 14:05:40 +02:00
translate_test.go TranslateFile - reopen the same instance 2019-05-02 14:05:40 +02:00
uri.go fix some lint warnings raised in VS-Code 2019-04-17 18:10:05 -05:00
uri_internal_test.go Require a valid port that isn't greater than 65,535 2018-08-16 21:05:41 -04:00
utils_internal_test.go add missing error check 2019-04-16 12:08:40 -05:00
version.go Fix linter issues: gochecknoinits 2018-07-18 11:58:27 -05:00
view.go Unbounded BSI w/ sign magnitude 2019-05-17 15:52:17 -06:00
view_internal_test.go view.go: deal with races in fragment creation 2019-02-21 16:43:19 -06:00

CircleCI GoDoc Go Report Card license CLA Assistant GitHub release

An open source, distributed bitmap index.

Want to contribute? One of the easiest ways is to tell us how you're using (or want to use) Pilosa. We learn from every discussion!

Docs

See our Documentation for information about installing and working with Pilosa.

Getting Started

  1. Install Pilosa.

  2. Start Pilosa with the default configuration:

    pilosa server
    

    and verify that it's running:

    curl localhost:10101/nodes
    
  3. Follow along with the Sample Project to get a better understanding of Pilosa's capabilities.

Data Model

Check out how the Pilosa Data Model works.

Query Language

You can interact with Pilosa directly in the console using the Pilosa Query Language (PQL).

Client Libraries

There are supported libraries for the following languages:

Licenses

The core Pilosa code base and all default builds (referred to as Pilosa Community Edition) are licensed completely under the Apache License, Version 2.0. If you build Pilosa with the enterprise build tag (Pilosa Enterprise Edition), then that build will include features licensed under the GNU Affero General Public License (AGPL). Enterprise code is located entirely in the github.com/pilosa/pilosa/enterprise directory. See github.com/pilosa/pilosa/NOTICE and github.com/pilosa/pilosa/LICENSE for more information about Pilosa licenses.

Get Support

There are several channels available for you to reach out to us for support.

Contributing

Pilosa is an open source project. Please see our Contributing Guide for information about how to get involved.